[Scummvm-cvs-logs] SF.net SVN: scummvm:[54904] tools/branches/gsoc2010-decompiler

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Tue Dec 14 04:14:12 CET 2010


Revision: 54904
          http://scummvm.svn.sourceforge.net/scummvm/?rev=54904&view=rev
Author:   pidgeot
Date:     2010-12-14 03:14:11 +0000 (Tue, 14 Dec 2010)

Log Message:
-----------
DECOMPILER: Objectify Instruction

*Major* restructuring in this revision.
All other disassemblers will require updates.
Documentation for all of this is coming soon.

Modified Paths:
--------------
    tools/branches/gsoc2010-decompiler/Makefile.common
    tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
    tools/branches/gsoc2010-decompiler/decompiler/codegen.h
    tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
    tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp
    tools/branches/gsoc2010-decompiler/decompiler/disassembler.h
    tools/branches/gsoc2010-decompiler/decompiler/engine.h
    tools/branches/gsoc2010-decompiler/decompiler/instruction.h
    tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
    tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h
    tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
    tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp
    tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h
    tools/branches/gsoc2010-decompiler/decompiler/simple_disassembler.h
    tools/branches/gsoc2010-decompiler/decompiler/stack.h
    tools/branches/gsoc2010-decompiler/decompiler/test/disassembler/pasc.cpp
    tools/branches/gsoc2010-decompiler/decompiler/test/disassembler/pasc.h
    tools/branches/gsoc2010-decompiler/decompiler/test/disassembler/subopcode.cpp
    tools/branches/gsoc2010-decompiler/decompiler/test/module.mk
    tools/branches/gsoc2010-decompiler/decompiler/value.h

Added Paths:
-----------
    tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp
    tools/branches/gsoc2010-decompiler/decompiler/wrongtype.h

Removed Paths:
-------------
    tools/branches/gsoc2010-decompiler/decompiler/engine.cpp

Modified: tools/branches/gsoc2010-decompiler/Makefile.common
===================================================================
--- tools/branches/gsoc2010-decompiler/Makefile.common	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/Makefile.common	2010-12-14 03:14:11 UTC (rev 54904)
@@ -230,9 +230,9 @@
 	common/file.o \
 	decompiler/decompiler.o \
 	decompiler/value.o \
+	decompiler/instruction.o \
 	decompiler/disassembler.o \
 	decompiler/simple_disassembler.o \
-	decompiler/engine.o \
 	decompiler/unknown_opcode.o \
 	decompiler/graph.o \
 	decompiler/control_flow.o \

Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -171,70 +171,40 @@
 }
 
 void CodeGenerator::processInst(const InstPtr inst) {
-	switch (inst->_type) {
-	// We handle plain dups here because their behavior should be identical across instruction sets and this prevents implementation error.
-	case kDupInstType:
-		{
-			std::stringstream s;
-			ValuePtr p = _stack.pop()->dup(s);
-			if (s.str().length() > 0)
-				addOutputLine(s.str());
-			_stack.push(p);
-			_stack.push(p);
+	inst->processInst(_stack, _engine, this);
+	if (inst->isCondJump()) {
+		std::stringstream s;
+		switch (_curGroup->_type) {
+		case kIfCondGroupType:
+			if (_curGroup->_startElse && _curGroup->_code.size() == 1) {
+				OutEdgeRange oer = boost::out_edges(_curVertex, _g);
+				bool coalesceElse = false;
+				for (OutEdgeIterator oe = oer.first; oe != oer.second; ++oe) {
+					GroupPtr oGr = GET(boost::target(*oe, _g))->_prev;
+					if (std::find(oGr->_endElse.begin(), oGr->_endElse.end(), _curGroup.get()) != oGr->_endElse.end())
+						coalesceElse = true;
+				}
+				if (coalesceElse) {
+					_curGroup->_code.clear();
+					_curGroup->_coalescedElse = true;
+					s << "} else ";
+				}
+			}
+			s << "if (" << _stack.pop()->negate() << ") {";
+			addOutputLine(s.str(), _curGroup->_coalescedElse, true);
 			break;
-		}
-	case kUnaryOpPreInstType:
-	case kUnaryOpPostInstType:
-		_stack.push(new UnaryOpValue(_stack.pop(), inst->_codeGenData, inst->_type == kUnaryOpPostInstType));
-		break;
-	case kBinaryOpInstType:
-		{
-			ValuePtr op1 = _stack.pop();
-			ValuePtr op2 = _stack.pop();
-			if (_binOrder == kFIFOArgOrder)
-				_stack.push(new BinaryOpValue(op2, op1, inst->_codeGenData));
-			else if (_binOrder == kLIFOArgOrder)
-				_stack.push(new BinaryOpValue(op1, op2, inst->_codeGenData));
+		case kWhileCondGroupType:
+			s << "while (" << _stack.pop()->negate() << ") {";
+			addOutputLine(s.str(), false, true);
 			break;
+		case kDoWhileCondGroupType:
+			s << "} while (" << _stack.pop() << ")";
+			addOutputLine(s.str(), true, false);
+			break;
+		default:
+			break;
 		}
-	case kCondJumpInstType:
-	case kCondJumpRelInstType:
-		{
-			std::stringstream s;
-			switch (_curGroup->_type) {
-			case kIfCondGroupType:
-				if (_curGroup->_startElse && _curGroup->_code.size() == 1) {
-					OutEdgeRange oer = boost::out_edges(_curVertex, _g);
-					bool coalesceElse = false;
-					for (OutEdgeIterator oe = oer.first; oe != oer.second; ++oe) {
-						GroupPtr oGr = GET(boost::target(*oe, _g))->_prev;
-						if (std::find(oGr->_endElse.begin(), oGr->_endElse.end(), _curGroup.get()) != oGr->_endElse.end())
-							coalesceElse = true;
-					}
-					if (coalesceElse) {
-						_curGroup->_code.clear();
-						_curGroup->_coalescedElse = true;
-						s << "} else ";
-					}
-				}
-				s << "if (" << _stack.pop()->negate() << ") {";
-				addOutputLine(s.str(), _curGroup->_coalescedElse, true);
-				break;
-			case kWhileCondGroupType:
-				s << "while (" << _stack.pop()->negate() << ") {";
-				addOutputLine(s.str(), false, true);
-				break;
-			case kDoWhileCondGroupType:
-				s << "} while (" << _stack.pop() << ")";
-				addOutputLine(s.str(), true, false);
-				break;
-			default:
-				break;
-			}
-		}
-		break;
-	case kJumpInstType:
-	case kJumpRelInstType:
+	} else if (inst->isUncondJump()) {
 		switch (_curGroup->_type) {
 		case kBreakGroupType:
 			addOutputLine("break;");
@@ -269,39 +239,12 @@
 				}
 				if (printJump) {
 					std::stringstream s;
-					s << boost::format("jump 0x%X;") % _engine->getDestAddress(inst);
+					s << boost::format("jump 0x%X;") % inst->getDestAddress();
 					addOutputLine(s.str());
 				}
 			}
 			break;
 		}
-		break;
-	case kReturnInstType:
-		// TODO: Allow specification of return value as part of return statement
-		addOutputLine("return;");
-		break;
-	case kSpecialCallInstType:
-		{
-			_argList.clear();
-			bool returnsValue = (inst->_codeGenData.find("r") == 0);
-			std::string metadata = (!returnsValue ? inst->_codeGenData : inst->_codeGenData.substr(1));
-			for (size_t i = 0; i < metadata.length(); i++)
-				processSpecialMetadata(inst, metadata[i], i);
-			_stack.push(new CallValue(inst->_name, _argList));
-			if (!returnsValue) {
-				std::stringstream stream;
-				stream << _stack.pop() << ";";
-				addOutputLine(stream.str());
-			}
-			break;
-		}
-	default:
-		{
-			std::stringstream s;
-			s << boost::format("WARNING: Unknown opcode %X at address %08X") % inst->_opcode % inst->_address;
-			addOutputLine(s.str());
-		}
-		break;
 	}
 }
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.h	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.h	2010-12-14 03:14:11 UTC (rev 54904)
@@ -21,7 +21,6 @@
  */
 
 #include "graph.h"
-#include "stack.h"
 #include "value.h"
 
 #include <ostream>
@@ -36,11 +35,6 @@
 
 class Function;
 
-/**
- * Type representing a stack.
- */
-typedef Stack<ValuePtr> ValueStack;
-
 const int kIndentAmount = 2; ///< How many spaces to use for each indent.
 
 /**
@@ -57,8 +51,6 @@
 class CodeGenerator {
 private:
 	Graph _g;                  ///< The annotated graph of the script.
-	const ArgOrder _binOrder;  ///< Order of operands for binary operations.
-	const ArgOrder _callOrder; ///< Order of operands for call arguments.
 
 	/**
 	 * Processes a GraphVertex.
@@ -73,8 +65,6 @@
 	ValueStack _stack;      ///< The stack currently being processed.
 	uint _indentLevel;      ///< Indentation level.
 	GraphVertex _curVertex; ///< Graph vertex currently being processed.
-	GroupPtr _curGroup;     ///< Pointer to the group currently being processed.
-	ValueList _argList;     ///< Storage for lists of arguments to be built when processing function calls.
 
 	/**
 	 * Processes an instruction. Called by process() for each instruction.
@@ -83,7 +73,7 @@
 	 *
 	 * @param inst The instruction to process.
 	 */
-	virtual void processInst(const InstPtr inst);
+	void processInst(const InstPtr inst);
 
 	/**
 	 * Indents a string according to the current indentation level.
@@ -94,6 +84,38 @@
 	std::string indentString(std::string s);
 
 	/**
+	 * Construct the signature for a function.
+	 *
+	 * @param func Reference to the function to construct the signature for.
+	 */
+	virtual std::string constructFuncSignature(const Function &func);
+
+public:
+	const ArgOrder _binOrder;  ///< Order of operands for binary operations.
+	const ArgOrder _callOrder; ///< Order of operands for call arguments.
+	ValueList _argList;        ///< Storage for lists of arguments to be built when processing function calls.
+	GroupPtr _curGroup;     ///< Pointer to the group currently being processed.
+
+	virtual ~CodeGenerator() { }
+
+	/**
+	 * Constructor for CodeGenerator.
+	 *
+	 * @param engine Pointer to the Engine used for the script.
+	 * @param output The std::ostream to output the code to.
+	 * @param binOrder Order of arguments for binary operators.
+	 * @param callOrder Order of arguments for function calls.
+	 */
+	CodeGenerator(Engine *engine, std::ostream &output, ArgOrder binOrder, ArgOrder callOrder);
+
+	/**
+	 * Generates code from the provided graph and outputs it to stdout.
+	 *
+	 * @param g The annotated graph of the script.
+	 */
+	void generate(const Graph &g);
+
+	/**
 	 * Adds a line of code to the current group.
 	 *
 	 * @param s The line to add.
@@ -111,15 +133,6 @@
 	void writeAssignment(ValuePtr dst, ValuePtr src);
 
 	/**
-	 * Process a single character of metadata.
-	 *
-	 * @param inst The instruction being processed.
-	 * @param c The character signifying the action to be taken.
-	 * @param pos The position at which c occurred in the metadata.
-	 */
-	virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
-
-	/**
 	 * Add an argument to the argument list.
 	 *
 	 * @param p The argument to add.
@@ -127,31 +140,14 @@
 	void addArg(ValuePtr p);
 
 	/**
-	 * Construct the signature for a function.
+	 * Process a single character of metadata.
 	 *
-	 * @param func Reference to the function to construct the signature for.
+	 * @param inst The instruction being processed.
+	 * @param c The character signifying the action to be taken.
+	 * @param pos The position at which c occurred in the metadata.
 	 */
-	virtual std::string constructFuncSignature(const Function &func);
+	virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
 
-public:
-	virtual ~CodeGenerator() { }
-
-	/**
-	 * Constructor for CodeGenerator.
-	 *
-	 * @param engine Pointer to the Engine used for the script.
-	 * @param output The std::ostream to output the code to.
-	 * @param binOrder Order of arguments for binary operators.
-	 * @param callOrder Order of arguments for function calls.
-	 */
-	CodeGenerator(Engine *engine, std::ostream &output, ArgOrder binOrder, ArgOrder callOrder);
-
-	/**
-	 * Generates code from the provided graph and outputs it to stdout.
-	 *
-	 * @param g The annotated graph of the script.
-	 */
-	void generate(const Graph &g);
 };
 
 #endif

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -77,24 +77,16 @@
 		}
 
 		last = cur;
-		addEdge = ((*it)->_type != kJumpInstType && (*it)->_type != kJumpRelInstType && (*it)->_type != kReturnInstType);
+		addEdge = !((*it)->isUncondJump() || (*it)->isReturn());
 		prev = GET(cur);
 
 	}
 
 	// Add jump edges
 	for (ConstInstIterator it = insts.begin(); it != insts.end(); ++it) {
-		switch((*it)->_type) {
-		case kJumpInstType:
-		case kCondJumpInstType:
-		case kJumpRelInstType:
-		case kCondJumpRelInstType: {
-			GraphEdge e = boost::add_edge(find(it), find(_engine->getDestAddress(it)), _g).first;
+		if ((*it)->isJump()) {
+			GraphEdge e = boost::add_edge(find(it), find((*it)->getDestAddress()), _g).first;
 			PUT_EDGE(e, true);
-			break;
-			}
-		default:
-			break;
 		}
 	}
 }
@@ -296,19 +288,19 @@
 		stackLevel += (*curInst)->_stackChange;
 
 		// For stack operations, the new stack level becomes the expected stack level starting from the next group
-		if ((*curInst)->_type == kStackInstType) {
+		if ((*curInst)->isStackOp()) {
 			expectedStackLevel = stackLevel;
 			grNext->_stackLevel = stackLevel;
 		}
 
 		// Group ends after a jump
-		if ((*curInst)->_type == kJumpInstType || (*curInst)->_type == kJumpRelInstType || (*curInst)->_type == kCondJumpInstType || (*curInst)->_type == kCondJumpRelInstType) {
+		if ((*curInst)->isJump()) {
 			stackLevel = grNext->_stackLevel;
 			continue;
 		}
 
 		// Group ends with a return
-		if ((*curInst)->_type == kReturnInstType) {
+		if ((*curInst)->isReturn()) {
 			stackLevel = grNext->_stackLevel;
 			continue;
 		}
@@ -329,7 +321,7 @@
 		} while (grCur->_start != grCur->_end && it != grCur->_end);
 
 		// Group ends when stack is balanced, unless just before conditional jump
-		if (stackLevel == expectedStackLevel && !forceMerge && (*nextInst)->_type != kCondJumpInstType && (*nextInst)->_type != kCondJumpRelInstType) {
+		if (stackLevel == expectedStackLevel && !forceMerge && !(*nextInst)->isCondJump()) {
 			continue;
 		}
 
@@ -433,7 +425,7 @@
 	for (VertexIterator v = vr.first; v != vr.second; ++v) {
 		GroupPtr gr = GET(*v);
 		// Undetermined block with unconditional jump...
-		if (gr->_type == kNormalGroupType && ((*gr->_end)->_type == kJumpInstType || (*gr->_end)->_type == kJumpRelInstType) && out_degree(*v, _g) == 1) {
+		if (gr->_type == kNormalGroupType && ((*gr->_end)->isUncondJump()) && out_degree(*v, _g) == 1) {
 			OutEdgeIterator oe = boost::out_edges(*v, _g).first;
 			GraphVertex target = boost::target(*oe, _g);
 			GroupPtr targetGr = GET(target);
@@ -458,7 +450,7 @@
 	for (VertexIterator v = vr.first; v != vr.second; ++v) {
 		GroupPtr gr = GET(*v);
 		// Undetermined block with unconditional jump...
-		if (gr->_type == kNormalGroupType && ((*gr->_end)->_type == kJumpInstType || (*gr->_end)->_type == kJumpRelInstType) && out_degree(*v, _g) == 1) {
+		if (gr->_type == kNormalGroupType && ((*gr->_end)->isUncondJump()) && out_degree(*v, _g) == 1) {
 			OutEdgeIterator oe = boost::out_edges(*v, _g).first;
 			GraphVertex target = boost::target(*oe, _g);
 			GroupPtr targetGr = GET(target);
@@ -527,7 +519,7 @@
 	for (VertexIterator v = vr.first; v != vr.second; ++v) {
 		GroupPtr gr = GET(*v);
 		// if: Undetermined block with conditional jump
-		if (gr->_type == kNormalGroupType && ((*gr->_end)->_type == kCondJumpInstType || (*gr->_end)->_type == kCondJumpRelInstType)) {
+		if (gr->_type == kNormalGroupType && ((*gr->_end)->isCondJump())) {
 			gr->_type = kIfCondGroupType;
 		}
 	}
@@ -552,7 +544,7 @@
 			}
 			targetGr = GET(target);
 			// else: Jump target of if immediately preceded by an unconditional jump...
-			if ((*targetGr->_prev->_end)->_type != kJumpInstType && (*targetGr->_prev->_end)->_type != kJumpRelInstType)
+			if (!(*targetGr->_prev->_end)->isUncondJump())
 				continue;
 			// ...which is not a break or a continue...
 			if (targetGr->_prev->_type == kContinueGroupType || targetGr->_prev->_type == kBreakGroupType)
@@ -592,7 +584,7 @@
 		}
 
 		// Unless group is a simple unconditional jump...
-		if ((*cursor->_start)->_type == kJumpInstType || (*cursor->_start)->_type == kJumpRelInstType)
+		if ((*cursor->_start)->isUncondJump())
 			continue;
 
 		// ...validate ingoing edges
@@ -606,7 +598,7 @@
 				// ...must not come from outside the range [start, end]...
 				if ((*start->_start)->_address > (*sourceGr->_start)->_address || (*sourceGr->_start)->_address > (*end->_start)->_address) {
 					// ...unless source is simple unconditional jump...
-					if ((*sourceGr->_start)->_type == kJumpInstType || (*sourceGr->_start)->_type == kJumpRelInstType)
+					if ((*sourceGr->_start)->isUncondJump())
 						continue;
 					// ...or the edge is from the if condition associated with this else
 					if (ifGroup == sourceGr)

Modified: tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -24,6 +24,13 @@
 
 Disassembler::Disassembler(InstVec &insts) : _insts(insts) {
 	_addressBase = 0;
+	_instFactory.addEntry<BinaryOpInstruction>(kBinaryOpInst);
+	_instFactory.addEntry<BoolNegateInstruction>(kBoolNegateInst);
+	_instFactory.addEntry<DupInstruction>(kDupInst);
+	_instFactory.addEntry<KernelCallInstruction>(kKernelCallInst);
+	_instFactory.addEntry<ReturnInstruction>(kReturnInst);
+	_instFactory.addEntry<UnaryOpPrefixInstruction>(kUnaryOpPreInst);
+	_instFactory.addEntry<UnaryOpPostfixInstruction>(kUnaryOpPostInst);
 }
 
 void Disassembler::open(const char *filename) {

Modified: tools/branches/gsoc2010-decompiler/decompiler/disassembler.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/disassembler.h	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/disassembler.h	2010-12-14 03:14:11 UTC (rev 54904)
@@ -29,15 +29,17 @@
 #include "instruction.h"
 #include "common/file.h"
 #include "unknown_opcode.h"
+#include "objectFactory.h"
 
 /**
  * Base class for disassemblers.
  */
 class Disassembler {
 protected:
-	Common::File _f;                  ///< Used to perform file I/O.
-	InstVec &_insts;                  ///< Container for disassembled instructions.
-	uint32 _addressBase;              ///< Base address where the script starts.
+	Common::File _f;                              ///< Used to perform file I/O.
+	InstVec &_insts;                              ///< Container for disassembled instructions.
+	uint32 _addressBase;                          ///< Base address where the script starts.
+	ObjectFactory<int, Instruction> _instFactory; ///< Factory for Instruction and subclasses
 
 	/**
 	 * Performs disassembly.

Deleted: tools/branches/gsoc2010-decompiler/decompiler/engine.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/engine.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/engine.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -1,27 +0,0 @@
-/* ScummVM Tools
- * Copyright (C) 2010 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "engine.h"
-
-uint32 Engine::getDestAddress(ConstInstIterator it) const {
-	return getDestAddress(*it);
-}

Modified: tools/branches/gsoc2010-decompiler/decompiler/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/engine.h	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/engine.h	2010-12-14 03:14:11 UTC (rev 54904)
@@ -81,14 +81,6 @@
 	/**
 	 * Decode a jump instruction to get the destination address.
 	 *
-	 * @param inst Instruction to decode.
-	 * @return The destination address of the jump instruction.
-	 */
-	virtual uint32 getDestAddress(const InstPtr inst) const = 0;
-
-	/**
-	 * Decode a jump instruction to get the destination address.
-	 *
 	 * @param it Iterator pointing to the instruction to decode.
 	 * @return The destination address of the jump instruction.
 	 */

Added: tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp	                        (rev 0)
+++ tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -0,0 +1,164 @@
+/* ScummVM Tools
+ * Copyright (C) 2010 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "instruction.h"
+#include "codegen.h"
+#include "engine.h"
+
+bool Instruction::isJump() const {
+	return false;
+}
+
+bool Instruction::isCondJump() const {
+	return false;
+}
+
+bool Instruction::isUncondJump() const {
+	return false;
+}
+
+bool Instruction::isStackOp() const {
+	return false;
+}
+
+bool Instruction::isFuncCall() const {
+	return false;
+}
+
+bool Instruction::isReturn() const {
+	return false;
+}
+
+bool Instruction::isKernelCall() const {
+	return false;
+}
+
+bool Instruction::isLoad() const {
+	return false;
+}
+
+bool Instruction::isStore() const {
+	return false;
+}
+
+uint32 Instruction::getDestAddress() const {
+	throw WrongTypeException();
+}
+
+std::ostream &Instruction::print(std::ostream &output) const {
+	output << boost::format("%08x: %s") % _address % _name;
+	std::vector<ValuePtr>::const_iterator param;
+	for (param = _params.begin(); param != _params.end(); ++param) {
+		if (param != _params.begin())
+			output << ",";
+		output << " " << *param;
+	}
+	output << boost::format(" (%d)") % _stackChange << "\n";
+	return output;
+}
+
+bool JumpInstruction::isJump() const {
+	return true;
+}
+
+bool CondJumpInstruction::isCondJump() const {
+	return true;
+}
+
+bool UncondJumpInstruction::isUncondJump() const {
+	return true;
+}
+
+void UncondJumpInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+}
+
+bool StackInstruction::isStackOp() const {
+	return true;
+}
+
+bool CallInstruction::isFuncCall() const {
+	return true;
+}
+
+bool LoadInstruction::isLoad() const {
+	return true;
+}
+
+bool StoreInstruction::isStore() const {
+	return true;
+}
+
+void DupInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	std::stringstream s;
+	ValuePtr p = stack.pop()->dup(s);
+	if (s.str().length() > 0)
+		codeGen->addOutputLine(s.str());
+	stack.push(p);
+	stack.push(p);
+}
+
+void BoolNegateInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	stack.push(stack.pop()->negate());
+}
+
+void BinaryOpInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	ValuePtr op1 = stack.pop();
+	ValuePtr op2 = stack.pop();
+	if (codeGen->_binOrder == kFIFOArgOrder)
+		stack.push(new BinaryOpValue(op2, op1, _codeGenData));
+	else if (codeGen->_binOrder == kLIFOArgOrder)
+		stack.push(new BinaryOpValue(op1, op2, _codeGenData));
+}
+
+bool ReturnInstruction::isReturn() const {
+	return true;
+}
+
+void ReturnInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	codeGen->addOutputLine("return;");
+}
+
+void UnaryOpPrefixInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	stack.push(new UnaryOpValue(stack.pop(), _codeGenData, false));
+}
+
+void UnaryOpPostfixInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	stack.push(new UnaryOpValue(stack.pop(), _codeGenData, true));
+}
+
+void KernelCallInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	codeGen->_argList.clear();
+	bool returnsValue = (_codeGenData.find("r") == 0);
+	std::string metadata = (!returnsValue ? _codeGenData : _codeGenData.substr(1));
+	for (size_t i = 0; i < metadata.length(); i++)
+		codeGen->processSpecialMetadata(this, metadata[i], i);
+	stack.push(new CallValue(_name, codeGen->_argList));
+	if (!returnsValue) {
+		std::stringstream stream;
+		stream << stack.pop() << ";";
+		codeGen->addOutputLine(stream.str());
+	}
+}
+
+bool KernelCallInstruction::isKernelCall() const {
+	return true;
+}


Property changes on: tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: tools/branches/gsoc2010-decompiler/decompiler/instruction.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/instruction.h	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/instruction.h	2010-12-14 03:14:11 UTC (rev 54904)
@@ -32,42 +32,52 @@
 #include "common/scummsys.h"
 #include "refcounted.h"
 #include "value.h"
+#include "wrongtype.h"
 
+class CodeGenerator;
+class Engine;
+
 /**
- * Enumeration for categorizing the different kinds of instructions.
+ * Constants for categorizing the different kinds of instructions.
  */
-enum InstType {
-	kBinaryOpInstType,    ///< Binary operation (e.g. +, &&, etc.), including comparisons.
-	kCallInstType,        ///< Regular function call.
-	kCondJumpInstType,    ///< Conditional jump (absolute address).
-	kCondJumpRelInstType, ///< Conditional jump (relative address).
-	kDupInstType,         ///< Instruction duplicates the most recent stack entry.
-	kJumpInstType,        ///< Unconditional jump (absolute address).
-	kJumpRelInstType,     ///< Unconditional jump (relative address).
-	kLoadInstType,        ///< Load value to stack.
-	kReturnInstType,      ///< Return from regular function call.
-	kSpecialCallInstType, ///< Special functions.
-	kStackInstType,       ///< Stack allocation or deallocation (altering stack pointer).
-	kStoreInstType,       ///< Store value from stack in memory.
-	kUnaryOpPreInstType,  ///< Unary operation (e.g. !) with operator placed before the operator.
-	kUnaryOpPostInstType  ///< Unary operation with operator placed after the operator.
-};
+const int kBinaryOpInst = 0;     ///< Binary operation (e.g. +, &&, etc.), including comparisons.
+const int kBoolNegateInst = 1;   ///< Boolean negation.
+const int kCallInst = 2;         ///< Regular function call.
+const int kCondJumpInst = 3;     ///< Conditional jump.
+const int kDupInst = 4;          ///< Instruction duplicates the most recent stack entry.
+const int kJumpInst = 5;         ///< Unconditional jump.
+const int kKernelCallInst = 6;   ///< Kernel functions.
+const int kLoadInst = 7;         ///< Load value to stack.
+const int kReturnInst = 8;       ///< Return from regular function call.
+const int kStackInst = 9;        ///< Stack allocation or deallocation (altering stack pointer)
+const int kStoreInst = 10;       ///< Store value from stack in memory.
+const int kUnaryOpPreInst = 11;  ///< Unary operation (e.g. !) with operator placed before the operator.
+const int kUnaryOpPostInst = 12; ///< Unary operation with operator placed after the operator.
 
+const int kFirstCustomInst = kUnaryOpPostInst + 1; ///< First unused key. Add your custom type keys starting with this value.
+
+struct Instruction;
+
 /**
+ * Pointer to an Instruction.
+ */
+typedef boost::intrusive_ptr<Instruction> InstPtr;
+
+/**
  * Structure for representing an instruction.
  */
 struct Instruction : public RefCounted {
+public:
 	uint32 _opcode;                 ///< The instruction opcode.
 	uint32 _address;                ///< The instruction address.
 	std::string _name;              ///< The instruction name (opcode name).
-	InstType _type;                 ///< The instruction type.
 	int16 _stackChange;             ///< How much this instruction changes the stack pointer by.
 	std::vector<ValuePtr> _params;  ///< Array of parameters used for the instruction.
 	std::string _codeGenData;       ///< String containing metadata for code generation. See the extended documentation for details.
 
 	Instruction(uint32 opcode = 0, uint32 address = 0,
-			std::string name = "", InstType type = kSpecialCallInstType, int16 stackChange = 0) :
-		_opcode(opcode), _address(address), _name(name), _type(type), _stackChange(stackChange) {}
+			std::string name = "", int16 stackChange = 0) :
+		_opcode(opcode), _address(address), _name(name), _stackChange(stackChange) {}
 
 	/**
 	 * Operator overload to output an Instruction to a std::ostream.
@@ -77,34 +87,99 @@
 	 * @return The std::ostream used for output.
 	 */
 	friend std::ostream &operator<<(std::ostream &output, const Instruction *inst) {
-		return output << *inst;
+		return inst->print(output);
 	}
 
-	/**
-	 * Operator overload to output an Instruction to a std::ostream.
-	 *
-	 * @param output The std::ostream to output to.
-	 * @param inst   The Instruction to output.
-	 * @return The std::ostream used for output.
-	 */
-	friend std::ostream &operator<<(std::ostream &output, const Instruction &inst) {
-		output << boost::format("%08x: %s") % inst._address % inst._name;
-		std::vector<ValuePtr>::const_iterator param;
-		for (param = inst._params.begin(); param != inst._params.end(); ++param) {
-			if (param != inst._params.begin())
-				output << ",";
-			output << " " << *param;
-		}
-		output << boost::format(" (%d)") % inst._stackChange << "\n";
-		return output;
-	}
+	virtual std::ostream &print(std::ostream &output) const;
+
+  virtual bool isJump() const;
+  virtual bool isCondJump() const;
+  virtual bool isUncondJump() const;
+  virtual bool isStackOp() const;
+	virtual bool isFuncCall() const;
+	virtual bool isReturn() const;
+	virtual bool isKernelCall() const;
+	virtual bool isLoad() const;
+	virtual bool isStore() const;
+  virtual uint32 getDestAddress() const;
+
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) = 0;
+
 };
 
-/**
- * Pointer to an Instruction.
- */
-typedef boost::intrusive_ptr<Instruction> InstPtr;
+struct JumpInstruction : public Instruction {
+public:
+	virtual bool isJump() const;
+};
 
+struct CondJumpInstruction : public JumpInstruction {
+public:
+	virtual bool isCondJump() const;
+};
+
+struct UncondJumpInstruction : public JumpInstruction {
+public:
+	virtual bool isUncondJump() const;
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct StackInstruction : public Instruction {
+public:
+	virtual bool isStackOp() const;
+};
+
+struct CallInstruction : public Instruction {
+public:
+	virtual bool isFuncCall() const;
+};
+
+struct LoadInstruction : public Instruction {
+public:
+	virtual bool isLoad() const;
+};
+
+struct StoreInstruction : public Instruction {
+public:
+	virtual bool isStore() const;
+};
+
+struct DupInstruction : public Instruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct BoolNegateInstruction : public Instruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct BinaryOpInstruction : public Instruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct ReturnInstruction : public Instruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+	virtual bool isReturn() const;
+};
+
+struct UnaryOpPrefixInstruction : public Instruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct UnaryOpPostfixInstruction : public Instruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct KernelCallInstruction : public Instruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+	virtual bool isKernelCall() const;
+};
+
 /**
  * Type representing a vector of InstPtrs.
  */

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -35,147 +35,10 @@
 	return s.str();
 }
 
-void Kyra::Kyra2CodeGenerator::processInst(const InstPtr inst) {
-	switch (inst->_type) {
-	case kLoadInstType:
-		switch (inst->_opcode) {
-		case 2:
-			// If something has been called previously in this group, don't output retval variable
-			if (inst->_address <= findFirstCall()->_address)
-				_stack.push(new VarValue("retval"));
-			break;
-		case 3:
-		case 4:
-			_stack.push(inst->_params[0]);
-			break;
-		case 5:
-			{
-				std::stringstream s;
-				s << boost::format("var%d") % inst->_params[0]->getSigned();
-				_stack.push(new VarValue(s.str()));
-			}
-			break;
-		case 6:
-			{
-				std::stringstream s;
-				s << boost::format("localvar%d") % inst->_params[0]->getSigned();
-				_stack.push(new VarValue(s.str()));
-			}
-			break;
-		case 7:
-			{
-				std::stringstream s;
-				s << boost::format("param%d") % inst->_params[0]->getSigned();
-				_stack.push(new VarValue(s.str()));
-			}
-			break;
-		}
-		break;
-	case kStoreInstType:
-		switch (inst->_opcode) {
-		case 8:
-			{
-				ValuePtr p = new VarValue("retval");
-				writeAssignment(p, _stack.pop());
-			}
-			break;
-		case 9:
-			{
-				std::stringstream s;
-				s << boost::format("var%d") % inst->_params[0]->getSigned();
-				ValuePtr p = new VarValue(s.str());
-				writeAssignment(p, _stack.pop());
-			}
-			break;
-		case 10:
-			{
-				std::stringstream s;
-				s << boost::format("localvar%d") % inst->_params[0]->getSigned();
-				ValuePtr p = new VarValue(s.str());
-				writeAssignment(p, _stack.pop());
-			}
-			break;
-		case 11:
-			{
-				std::stringstream s;
-				s << boost::format("param%d") % inst->_params[0]->getSigned();
-				ValuePtr p = new VarValue(s.str());
-				writeAssignment(p, _stack.pop());
-			}
-			break;
-		}
-		break;
-	case kStackInstType:
-		if (inst->_opcode == 12) {
-			for (int i = inst->_params[0]->getSigned(); i != 0; --i) {
-				if (!_stack.empty())
-					_stack.pop();
-			}
-		} else if (inst->_opcode == 13) {
-			for (int i = 0; i != inst->_params[0]->getSigned(); ++i) {
-				std::stringstream s;
-				s << boost::format("localvar%d") % i;
-				_stack.push(new VarValue(s.str()));
-			}
-		}
-		break;
-	case kCondJumpInstType:
-		_stack.push(_stack.pop()->negate());
-		CodeGenerator::processInst(inst);
-		break;
-	case kCallInstType:
-		{
-			_argList.clear();
-			Function f = _engine->_functions.find(inst->_params[0]->getUnsigned())->second;
-			for (size_t i = 0; i < f._metadata.length(); i++)
-				processSpecialMetadata(inst, f._metadata[i], i);
-			_stack.push(new CallValue(f._name, _argList));
-			// Leave call on stack if this is a condition, or other calls follow in same group
-			if (_curGroup->_type == kIfCondGroupType || _curGroup->_type == kWhileCondGroupType || _curGroup->_type == kDoWhileCondGroupType || inst->_address != findLastCall()->_address) {
-				break;
-			}	else if (!f._retVal) {
-				std::stringstream stream;
-				stream << _stack.pop() << ";";
-				addOutputLine(stream.str());
-			} else {
-				ValuePtr p = new VarValue("retval");
-				writeAssignment(p, _stack.pop());
-			}
-			break;
-		}
-	case kSpecialCallInstType:
-		{
-			if (inst->_opcode != 14)
-				return;
-			_argList.clear();
-			bool returnsValue = (inst->_codeGenData.find("r") == 0);
-			std::string metadata = (!returnsValue ? inst->_codeGenData : inst->_codeGenData.substr(1));
-			for (size_t i = 0; i < metadata.length(); i++)
-				processSpecialMetadata(inst, metadata[i], i);
-			_stack.push(new CallValue(inst->_name, _argList));
-			// Leave call on stack if this is a condition, or other calls follow in same group
-			if (_curGroup->_type == kIfCondGroupType || _curGroup->_type == kWhileCondGroupType || _curGroup->_type == kDoWhileCondGroupType || inst->_address != findLastCall()->_address) {
-				break;
-			}	else if (!returnsValue) {
-				std::stringstream stream;
-				stream << _stack.pop() << ";";
-				addOutputLine(stream.str());
-			} else {
-				ValuePtr p = new VarValue("retval");
-				writeAssignment(p, _stack.pop());
-			}
-			break;
-		}
-	default:
-		CodeGenerator::processInst(inst);
-		break;
-	}
-}
-
 const InstPtr Kyra::Kyra2CodeGenerator::findFirstCall() {
 	ConstInstIterator it = _curGroup->_start;
 	do {
-		if ((*it)->_type == kCallInstType || ((*it)->_type == kSpecialCallInstType && (*it)->_opcode == 14))
+		if ((*it)->isFuncCall() || ((*it)->isKernelCall() && (*it)->_opcode == 14))
 			return *it;
 	} while (it++ != _curGroup->_end);
 
@@ -185,7 +48,7 @@
 const InstPtr Kyra::Kyra2CodeGenerator::findLastCall() {
 	ConstInstIterator it = _curGroup->_end;
 	do {
-		if ((*it)->_type == kCallInstType || ((*it)->_type == kSpecialCallInstType && (*it)->_opcode == 14))
+		if ((*it)->isFuncCall() || ((*it)->isKernelCall() && (*it)->_opcode == 14))
 			return *it;
 	} while (it-- != _curGroup->_start);
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h	2010-12-14 03:14:11 UTC (rev 54904)
@@ -31,10 +31,18 @@
  * KYRA code generator.
  */
 class Kyra2CodeGenerator : public CodeGenerator {
-private:
+public:
 	/**
+	 * Constructor for Kyra2CodeGenerator.
+	 *
+	 * @param engine Pointer to the Engine used for the script.
+	 * @param output The std::ostream to output the code to.
+	 */
+	Kyra2CodeGenerator(Engine *engine, std::ostream &output) : CodeGenerator(engine, output, kFIFOArgOrder, kLIFOArgOrder) {}
+
+	/**
 	 * Finds the first call instruction in the current group and returns it.
-	 * The call may either be a kCallInstType or kSpecialCallInstType.
+	 * The call may either be a kCallInst or kKernelCallInst.
 	 * Used to check whether retVal should be output by pushRet.
 	 *
 	 * @return The first call instruction in the current group. If no calls are found, returns the first instruction.
@@ -43,23 +51,16 @@
 
 	/**
 	 * Finds the last call instruction in the current group and returns it.
-	 * The call may either be a kCallInstType or kSpecialCallInstType.
+	 * The call may either be a kCallInst or kKernelCallInst.
 	 * Used to check whether retVal should be output by calls.
 	 *
 	 * @return The last call instruction in the current group. If no calls are found, returns the last instruction.
 	 */
 	const InstPtr findLastCall();
-public:
-	/**
-	 * Constructor for Kyra2CodeGenerator.
-	 *
-	 * @param engine Pointer to the Engine used for the script.
-	 * @param output The std::ostream to output the code to.
-	 */
-	Kyra2CodeGenerator(Engine *engine, std::ostream &output) : CodeGenerator(engine, output, kFIFOArgOrder, kLIFOArgOrder) {}
+
+	virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
+
 protected:
-	void processInst(const InstPtr inst);
-	virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
 	std::string constructFuncSignature(const Function &func);
 };
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -266,6 +266,13 @@
 
 Kyra::Kyra2Disassembler::Kyra2Disassembler(Kyra2Engine *engine, InstVec &insts) : Disassembler(insts), _engine(engine) {
 	setupKyra2Funcs();
+	_instFactory.addEntry<Kyra2CallInstruction>(kCallInst);
+	_instFactory.addEntry<Kyra2CondJumpInstruction>(kCondJumpInst);
+	_instFactory.addEntry<Kyra2UncondJumpInstruction>(kJumpInst);
+	_instFactory.addEntry<Kyra2KernelCallInstruction>(kKernelCallInst);
+	_instFactory.addEntry<Kyra2LoadInstruction>(kLoadInst);
+	_instFactory.addEntry<Kyra2StackInstruction>(kStackInst);
+	_instFactory.addEntry<Kyra2StoreInstruction>(kStoreInst);
 }
 
 Kyra::Kyra2Disassembler::~Kyra2Disassembler() {
@@ -388,15 +395,14 @@
 			parameter = 0;
 		}
 
-#define ADD_INST _insts.insert(_insts.end(), new Instruction());
+#define ADD_INST(category) _insts.push_back(_instFactory.create(category));
 #define LAST_INST (_insts.back())
 #define OPCODE_MD(name, category, stackChange, hasParam, isSigned, isAddress, codeGenData) \
-		ADD_INST; \
+		ADD_INST(category); \
 		LAST_INST->_opcode = opcode; \
 		LAST_INST->_address = address; \
 		LAST_INST->_stackChange = stackChange; \
 		LAST_INST->_name = name; \
-		LAST_INST->_type = category; \
 		LAST_INST->_codeGenData = codeGenData; \
 		if (hasParam) { \
 			ValuePtr p; \
@@ -416,16 +422,16 @@
 			parameter *= 2;
 			if (parameter < minFuncAddr)
 				jumpTargets.insert(_insts.size());
-			OPCODE("jumpTo", kJumpInstType, 0, true, false, true);
+			OPCODE("jumpTo", kJumpInst, 0, true, false, true);
 			break;
 		case 1:
-			OPCODE("setRetValue", kStoreInstType, 0, true, true, false);
+			OPCODE("setRetValue", kStoreInst, 0, true, true, false);
 			break;
 		case 2:
 			if (parameter == 0) {
-				OPCODE("pushRet", kLoadInstType, 1, false, false, false);
+				OPCODE("pushRet", kLoadInst, 1, false, false, false);
 			} else if (parameter == 1) {
-				OPCODE("pushPos", kSpecialCallInstType, 0, false, false, false); // Sets up function call
+				OPCODE("pushPos", kKernelCallInst, 0, false, false, false); // Sets up function call
 			} else {
 				// Error: invalid parameter halts execution
 				throw UnknownOpcodeException(address, opcode);
@@ -433,41 +439,41 @@
 			break;
 		case 3:
 		case 4:
-			OPCODE("push", kLoadInstType, 1, true, true, false);
+			OPCODE("push", kLoadInst, 1, true, true, false);
 			break;
 		case 5:
-			OPCODE("pushVar", kLoadInstType, 1, true, true, false);
+			OPCODE("pushVar", kLoadInst, 1, true, true, false);
 			break;
 		case 6:
-			OPCODE("pushBPNeg", kLoadInstType, 1, true, true, false);
+			OPCODE("pushBPNeg", kLoadInst, 1, true, true, false);
 			break;
 		case 7:
-			OPCODE("pushBPAdd", kLoadInstType, 1, true, true, false);
+			OPCODE("pushBPAdd", kLoadInst, 1, true, true, false);
 			break;
 		case 8:
 			if (parameter == 0) {
-				OPCODE("popRet", kStoreInstType, -1, false, false, false);
+				OPCODE("popRet", kStoreInst, -1, false, false, false);
 			} else if (parameter == 1) {
-				OPCODE("popPos", kReturnInstType, 0, false, false, false); // Returns from function call
+				OPCODE("popPos", kReturnInst, 0, false, false, false); // Returns from function call
 			} else {
 				// Error: invalid parameter halts execution
 				throw UnknownOpcodeException(address, opcode);
 			}
 			break;
 		case 9:
-			OPCODE("popVar", kStoreInstType, -1, true, true, false);
+			OPCODE("popVar", kStoreInst, -1, true, true, false);
 			break;
 		case 10:
-			OPCODE("popBPNeg", kStoreInstType, -1, true, true, false);
+			OPCODE("popBPNeg", kStoreInst, -1, true, true, false);
 			break;
 		case 11:
-			OPCODE("popBPAdd", kStoreInstType, -1, true, true, false);
+			OPCODE("popBPAdd", kStoreInst, -1, true, true, false);
 			break;
 		case 12:
-			OPCODE("addSP", kStackInstType, -parameter, true, true, false);
+			OPCODE("addSP", kStackInst, -parameter, true, true, false);
 			break;
 		case 13:
-			OPCODE("subSP", kStackInstType, parameter, true, true, false);
+			OPCODE("subSP", kStackInst, parameter, true, true, false);
 			break;
 		case 14:
 			parameter = (uint8)parameter;
@@ -475,21 +481,21 @@
 				// Error: unknown function
 				throw UnknownOpcodeException(address, opcode);
 			}
-			OPCODE_MD(_funcs[parameter]._name, kSpecialCallInstType, 0, false, false, false, _funcs[parameter]._metadata)
+			OPCODE_MD(_funcs[parameter]._name, kKernelCallInst, 0, false, false, false, _funcs[parameter]._metadata)
 			break;
 		case 15:
 			parameter *= 2;
 			if (parameter < minFuncAddr)
 				jumpTargets.insert(_insts.size());
-			OPCODE("ifNotJmp", kCondJumpInstType, -1, true, false, true);
+			OPCODE("ifNotJmp", kCondJumpInst, -1, true, false, true);
 			break;
 		case 16:
 			if (parameter == 0) {
-				OPCODE_MD("boolNegate", kUnaryOpPreInstType, 0, false, false, false, "!");
+				OPCODE("boolNegate", kBoolNegateInst, 0, false, false, false);
 			} else if (parameter == 1) {
-				OPCODE_MD("arithmeticNegate", kUnaryOpPreInstType, 0, false, false, false,"-");
+				OPCODE_MD("arithmeticNegate", kUnaryOpPreInst, 0, false, false, false,"-");
 			} else if (parameter == 2) {
-				OPCODE_MD("bitwiseNegate", kUnaryOpPreInstType, 0, false, false, false, "~");
+				OPCODE_MD("bitwiseNegate", kUnaryOpPreInst, 0, false, false, false, "~");
 			} else {
 				// Error: invalid parameter halts execution
 				throw UnknownOpcodeException(address, opcode);
@@ -498,58 +504,58 @@
 		case 17:
 			switch (parameter) {
 				case 0:
-					OPCODE_MD("eval_band", kBinaryOpInstType, -1, false, false, false, "&&");
+					OPCODE_MD("eval_band", kBinaryOpInst, -1, false, false, false, "&&");
 					break;
 				case 1:
-					OPCODE_MD("eval_bor", kBinaryOpInstType, -1, false, false, false, "||");
+					OPCODE_MD("eval_bor", kBinaryOpInst, -1, false, false, false, "||");
 					break;
 				case 2:
-					OPCODE_MD("eval_eq", kBinaryOpInstType, -1, false, false, false, "==");
+					OPCODE_MD("eval_eq", kBinaryOpInst, -1, false, false, false, "==");
 					break;
 				case 3:
-					OPCODE_MD("eval_neq", kBinaryOpInstType, -1, false, false, false, "!=");
+					OPCODE_MD("eval_neq", kBinaryOpInst, -1, false, false, false, "!=");
 					break;
 				case 4:
-					OPCODE_MD("eval_leq", kBinaryOpInstType, -1, false, false, false, "<=");
+					OPCODE_MD("eval_leq", kBinaryOpInst, -1, false, false, false, "<=");
 					break;
 				case 5:
-					OPCODE_MD("eval_lt", kBinaryOpInstType, -1, false, false, false, "<");
+					OPCODE_MD("eval_lt", kBinaryOpInst, -1, false, false, false, "<");
 					break;
 				case 6:
-					OPCODE_MD("eval_geq", kBinaryOpInstType, -1, false, false, false, ">=");
+					OPCODE_MD("eval_geq", kBinaryOpInst, -1, false, false, false, ">=");
 					break;
 				case 7:
-					OPCODE_MD("eval_gt", kBinaryOpInstType, -1, false, false, false, ">");
+					OPCODE_MD("eval_gt", kBinaryOpInst, -1, false, false, false, ">");
 					break;
 				case 8:
-					OPCODE_MD("eval_add", kBinaryOpInstType, -1, false, false, false, "+");
+					OPCODE_MD("eval_add", kBinaryOpInst, -1, false, false, false, "+");
 					break;
 				case 9:
-					OPCODE_MD("eval_sub", kBinaryOpInstType, -1, false, false, false, "-");
+					OPCODE_MD("eval_sub", kBinaryOpInst, -1, false, false, false, "-");
 					break;
 				case 10:
-					OPCODE_MD("eval_mult", kBinaryOpInstType, -1, false, false, false, "*");
+					OPCODE_MD("eval_mult", kBinaryOpInst, -1, false, false, false, "*");
 					break;
 				case 11:
-					OPCODE_MD("eval_div", kBinaryOpInstType, -1, false, false, false, "/");
+					OPCODE_MD("eval_div", kBinaryOpInst, -1, false, false, false, "/");
 					break;
 				case 12:
-					OPCODE_MD("eval_shr", kBinaryOpInstType, -1, false, false, false, ">>");
+					OPCODE_MD("eval_shr", kBinaryOpInst, -1, false, false, false, ">>");
 					break;
 				case 13:
-					OPCODE_MD("eval_shl", kBinaryOpInstType, -1, false, false, false, "<<");
+					OPCODE_MD("eval_shl", kBinaryOpInst, -1, false, false, false, "<<");
 					break;
 				case 14:
-					OPCODE_MD("eval_land", kBinaryOpInstType, -1, false, false, false, "&");
+					OPCODE_MD("eval_land", kBinaryOpInst, -1, false, false, false, "&");
 					break;
 				case 15:
-					OPCODE_MD("eval_lor", kBinaryOpInstType, -1, false, false, false, "|");
+					OPCODE_MD("eval_lor", kBinaryOpInst, -1, false, false, false, "|");
 					break;
 				case 16:
-					OPCODE_MD("eval_mod", kBinaryOpInstType, -1, false, false, false, "%");
+					OPCODE_MD("eval_mod", kBinaryOpInst, -1, false, false, false, "%");
 					break;
 				case 17:
-					OPCODE_MD("eval_xor", kBinaryOpInstType, -1, false, false, false, "^");
+					OPCODE_MD("eval_xor", kBinaryOpInst, -1, false, false, false, "^");
 					break;
 				default:
 					// Error: invalid parameter halts execution
@@ -558,7 +564,7 @@
 			}
 			break;
 		case 18:
-			OPCODE("setRetAndJmp", kSpecialCallInstType, -2, false, false, false);
+			OPCODE("setRetAndJmp", kKernelCallInst, -2, false, false, false);
 			break;
 		default:
 			throw UnknownOpcodeException(i*2, code);
@@ -585,9 +591,16 @@
 	// Correct jumps to functions so they're treated as calls
 	bool lastWasPushPos = false;
 	for (InstIterator it = _insts.begin(); it != _insts.end(); ++it) {
-		if ((*it)->_type == kJumpInstType || (*it)->_type == kCondJumpInstType) {
+		if ((*it)->isJump()) {
 			if (lastWasPushPos || _engine->_functions.find((*it)->_params[0]->getUnsigned()) != _engine->_functions.end()) {
-				(*it)->_type = kCallInstType;
+				InstPtr p = _instFactory.create(kCallInst);
+				p->_opcode = (*it)->_opcode;
+				p->_address = (*it)->_address;
+				p->_stackChange = (*it)->_stackChange;
+				p->_name = (*it)->_name;
+				p->_codeGenData = (*it)->_codeGenData;
+				p->_params = (*it)->_params;
+				*it = p;
 			}
 		}
 		lastWasPushPos = ((*it)->_name.compare("pushPos") == 0);

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -32,10 +32,6 @@
 	return new Kyra2Disassembler(this, insts);
 }
 
-uint32 Kyra::Kyra2Engine::getDestAddress(const InstPtr inst) const {
-	return inst->_params[0]->getUnsigned();
-}
-
 CodeGenerator *Kyra::Kyra2Engine::getCodeGenerator(std::ostream &output) {
 	return new Kyra2CodeGenerator(this, output);
 }
@@ -63,3 +59,145 @@
 bool Kyra::Kyra2Engine::detectMoreFuncs() const {
 	return true;
 }
+
+void Kyra::Kyra2LoadInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	Kyra2CodeGenerator* cg = (Kyra2CodeGenerator *)codeGen;
+	switch (_opcode) {
+	case 2:
+		// If something has been called previously in this group, don't output retval variable
+		if (_address <= cg->findFirstCall()->_address)
+			stack.push(new VarValue("retval"));
+		break;
+	case 3:
+	case 4:
+		stack.push(_params[0]);
+		break;
+	case 5:
+		{
+			std::stringstream s;
+			s << boost::format("var%d") % _params[0]->getSigned();
+			stack.push(new VarValue(s.str()));
+		}
+		break;
+	case 6:
+		{
+			std::stringstream s;
+			s << boost::format("localvar%d") % _params[0]->getSigned();
+			stack.push(new VarValue(s.str()));
+		}
+		break;
+	case 7:
+		{
+			std::stringstream s;
+			s << boost::format("param%d") % _params[0]->getSigned();
+			stack.push(new VarValue(s.str()));
+		}
+		break;
+	}
+}
+
+void Kyra::Kyra2StoreInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	Kyra2CodeGenerator* cg = (Kyra2CodeGenerator *)codeGen;
+	switch (_opcode) {
+	case 8:
+		{
+			ValuePtr p = new VarValue("retval");
+			cg->writeAssignment(p, stack.pop());
+		}
+		break;
+	case 9:
+		{
+			std::stringstream s;
+			s << boost::format("var%d") % _params[0]->getSigned();
+			ValuePtr p = new VarValue(s.str());
+			cg->writeAssignment(p, stack.pop());
+		}
+		break;
+	case 10:
+		{
+			std::stringstream s;
+			s << boost::format("localvar%d") % _params[0]->getSigned();
+			ValuePtr p = new VarValue(s.str());
+			cg->writeAssignment(p, stack.pop());
+		}
+		break;
+	case 11:
+		{
+			std::stringstream s;
+			s << boost::format("param%d") % _params[0]->getSigned();
+			ValuePtr p = new VarValue(s.str());
+			cg->writeAssignment(p, stack.pop());
+		}
+		break;
+	}
+}
+
+void Kyra::Kyra2StackInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	if (_opcode == 12) {
+		for (int i = _params[0]->getSigned(); i != 0; --i) {
+			if (!stack.empty())
+				stack.pop();
+		}
+	} else if (_opcode == 13) {
+		for (int i = 0; i != _params[0]->getSigned(); ++i) {
+			std::stringstream s;
+			s << boost::format("localvar%d") % i;
+			stack.push(new VarValue(s.str()));
+		}
+	}
+}
+
+void Kyra::Kyra2CondJumpInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	stack.push(stack.pop()->negate());
+}
+
+uint32 Kyra::Kyra2CondJumpInstruction::getDestAddress() const {
+	return _params[0]->getUnsigned();
+}
+
+uint32 Kyra::Kyra2UncondJumpInstruction::getDestAddress() const {
+	return _params[0]->getUnsigned();
+}
+
+void Kyra::Kyra2CallInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	Kyra2CodeGenerator* cg = (Kyra2CodeGenerator *)codeGen;
+	cg->_argList.clear();
+	Function f = engine->_functions.find(_params[0]->getUnsigned())->second;
+	for (size_t i = 0; i < f._metadata.length(); i++)
+		cg->processSpecialMetadata(this, f._metadata[i], i);
+	stack.push(new CallValue(f._name, cg->_argList));
+	// Leave call on stack if this is a condition, or other calls follow in same group
+	if (cg->_curGroup->_type == kIfCondGroupType || cg->_curGroup->_type == kWhileCondGroupType || cg->_curGroup->_type == kDoWhileCondGroupType || _address != cg->findLastCall()->_address) {
+		return;
+	}	else if (!f._retVal) {
+		std::stringstream stream;
+		stream << stack.pop() << ";";
+		cg->addOutputLine(stream.str());
+	} else {
+		ValuePtr p = new VarValue("retval");
+		cg->writeAssignment(p, stack.pop());
+	}
+}
+
+void Kyra::Kyra2KernelCallInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	Kyra2CodeGenerator* cg = (Kyra2CodeGenerator *)codeGen;
+	if (_opcode != 14)
+		return;
+	cg->_argList.clear();
+	bool returnsValue = (_codeGenData.find("r") == 0);
+	std::string metadata = (!returnsValue ? _codeGenData : _codeGenData.substr(1));
+	for (size_t i = 0; i < metadata.length(); i++)
+		cg->processSpecialMetadata(this, metadata[i], i);
+	stack.push(new CallValue(_name, cg->_argList));
+	// Leave call on stack if this is a condition, or other calls follow in same group
+	if (cg->_curGroup->_type == kIfCondGroupType || cg->_curGroup->_type == kWhileCondGroupType || cg->_curGroup->_type == kDoWhileCondGroupType || _address != cg->findLastCall()->_address) {
+		return;
+	}	else if (!returnsValue) {
+		std::stringstream stream;
+		stream << stack.pop() << ";";
+		cg->addOutputLine(stream.str());
+	} else {
+		ValuePtr p = new VarValue("retval");
+		cg->writeAssignment(p, stack.pop());
+	}
+}

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h	2010-12-14 03:14:11 UTC (rev 54904)
@@ -36,7 +36,6 @@
 class Kyra2Engine : public Engine {
 public:
 	Disassembler *getDisassembler(InstVec &insts);
-	uint32 getDestAddress(const InstPtr inst) const;
 	CodeGenerator *getCodeGenerator(std::ostream &output);
 	void postCFG(InstVec &insts, Graph g);
 	bool detectMoreFuncs() const;
@@ -44,6 +43,42 @@
 	std::vector<std::string> _textStrings; ///< Container for strings from the TEXT chunk.
 };
 
+class Kyra2LoadInstruction : public LoadInstruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+class Kyra2StoreInstruction : public StoreInstruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+class Kyra2StackInstruction : public StackInstruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+class Kyra2CondJumpInstruction : public CondJumpInstruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+	virtual uint32 getDestAddress() const;
+};
+
+class Kyra2UncondJumpInstruction : public UncondJumpInstruction {
+public:
+	virtual uint32 getDestAddress() const;
+};
+
+class Kyra2CallInstruction : public CallInstruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+class Kyra2KernelCallInstruction : public KernelCallInstruction {
+public:
+	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
 } // End of namespace Kyra
 
 #endif

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -45,164 +45,6 @@
 	return new ListValue(list);
 }
 
-void Scumm::v6::Scummv6CodeGenerator::processInst(const InstPtr inst) {
-	// This is just to keep some order in this code and have related
-	// opcodes near each other. It's not strictly necessary, because we
-	// can just look directly at the opcode, but this should be easier
-	// to read.
-	switch (inst->_type) {
-	case kLoadInstType:
-		switch (inst->_opcode) {
-		case 0x00: // pushByte
-		case 0x01: // pushWord
-			_stack.push(inst->_params[0]);
-			break;
-		case 0x02: // pushByteVar
-		case 0x03: // pushWordVar
-			_stack.push(new VarValue(decodeVarName(inst->_params[0]->getUnsigned())));
-			break;
-		case 0x06: // byteArrayRead
-		case 0x07: // wordArrayRead
-			{
-				ValueList idxs;
-				idxs.push_front(_stack.pop());
-				_stack.push(new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs));
-				break;
-			}
-		case 0x0A: // byteArrayIndexedRead
-		case 0x0B: // wordArrayIndexedRead
-			{
-				ValueList idxs;
-				idxs.push_front(_stack.pop());
-				idxs.push_front(_stack.pop());
-				_stack.push(new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs));
-				break;
-			}
-		}
-		break;
-	case kStoreInstType:
-		switch (inst->_opcode) {
-			case 0x42: // writeByteVar
-			case 0x43: // writeWordVar
-				{
-					ValuePtr p = new VarValue(decodeVarName(inst->_params[0]->getUnsigned()));
-					writeAssignment(p, _stack.pop());
-				}
-				break;
-			case 0x46: // byteArrayWrite
-			case 0x47: // wordArrayWrite
-				{
-					ValuePtr value = _stack.pop();
-					ValueList idxs;
-					idxs.push_back(_stack.pop());
-					ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
-					writeAssignment(p, value);
-				}
-				break;
-			case 0x4A: // byteArrayIndexedWrite
-			case 0x4B: // wordArrayIndexedWrite
-				{
-					ValuePtr value = _stack.pop();
-					ValueList idxs;
-					idxs.push_front(_stack.pop());
-					idxs.push_front(_stack.pop());
-					ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
-					writeAssignment(p, value);
-				}
-				break;
-			default:
-				{
-					std::stringstream s;
-					s << boost::format("WARNING: Unknown opcode %X at address %08X") % inst->_opcode % inst->_address;
-					addOutputLine(s.str());
-				}
-				break;
-		}
-		break;
-	case kStackInstType:
-		// Only two opcodes in SCUMMv6, 0x1A and 0xA7: both are single item pop
-		_stack.pop();
-		//addOutputLine("// pop();");
-		break;
-	case kCondJumpRelInstType:
-		if (inst->_opcode == 0x5D) // jumpFalse
-			_stack.push(_stack.pop()->negate());
-		CodeGenerator::processInst(inst);
-		break;
-	case kUnaryOpPostInstType:
-		switch (inst->_opcode) {
-		case 0x4E: // byteVarInc
-		case 0x4F: // wordVarInc
-		case 0x56: // byteVarDec
-		case 0x57: // wordVarDec
-			{
-				std::stringstream s;
-				ValuePtr p = new UnaryOpValue(new VarValue(decodeVarName(inst->_params[0]->getUnsigned())), inst->_codeGenData, true);
-				s << p << ";";
-				addOutputLine(s.str());
-			}
-			break;
-		case 0x52: // byteArrayInc
-		case 0x53: // wordArrayInc
-		case 0x5A: // byteArrayDec
-		case 0x5B: // wordArrayDec
-			{
-				std::stringstream s;
-				ValueList idxs;
-				idxs.push_front(_stack.pop());
-				ValuePtr p = new UnaryOpValue(new ArrayValue(decodeVarName(inst->_params[0]->getUnsigned()), idxs), inst->_codeGenData, true);
-				s << p << ";";
-				addOutputLine(s.str());
-			}
-			break;
-		default:
-			CodeGenerator::processInst(inst);
-			break;
-		}
-		break;
-	case kSpecialCallInstType:
-		switch (inst->_opcode) {
-		case 0xA4CD: // arrayOp_assignString
-			{
-				ValuePtr value = new StringValue(inst->_params[1]->getString());
-				ValueList idxs;
-				idxs.push_front(_stack.pop());
-				ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
-				writeAssignment(p, value);
-			}
-			break;
-		case 0xA4D0: // arrayOp_assignIntList
-			{
-				ValueList idxs;
-				idxs.push_front(_stack.pop());
-				ValuePtr value = createListValue();
-				ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
-				writeAssignment(p, value);
-			}
-
-			break;
-		case 0xA4D4: // arrayOp_assign2DimList
-			{
-				ValueList idxs;
-				idxs.push_front(_stack.pop());
-				ValuePtr value = createListValue();
-				idxs.push_front(_stack.pop());
-				ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
-				writeAssignment(p, value);
-			}
-
-			break;
-		default:
-			CodeGenerator::processInst(inst);
-			break;
-		}
-		break;
-	default:
-		CodeGenerator::processInst(inst);
-		break;
-	}
-}
-
 const char *var_names[] = {
 	/* 0 */
 	NULL,

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h	2010-12-14 03:14:11 UTC (rev 54904)
@@ -48,8 +48,16 @@
  * SCUMMv6 code generator.
  */
 class Scummv6CodeGenerator : public CodeGenerator {
-private:
+public:
 	/**
+	 * Constructor for Scumm::v6::CodeGenerator.
+	 *
+	 * @param engine Pointer to the Engine used for the script.
+	 * @param output The std::ostream to output the code to.
+	 */
+	Scummv6CodeGenerator(Engine *engine, std::ostream &output) : CodeGenerator(engine, output, kFIFOArgOrder, kFIFOArgOrder) {}
+
+	/**
 	 * Get the name associated with a variable ID.
 	 *
 	 * @param varID The ID to get the name for.
@@ -79,16 +87,7 @@
 	 * @return The ListValue created from the stack.
 	 */
 	ValuePtr createListValue();
-public:
-	/**
-	 * Constructor for Scumm::v6::CodeGenerator.
-	 *
-	 * @param engine Pointer to the Engine used for the script.
-	 * @param output The std::ostream to output the code to.
-	 */
-	Scummv6CodeGenerator(Engine *engine, std::ostream &output) : CodeGenerator(engine, output, kFIFOArgOrder, kFIFOArgOrder) {}
-protected:
-	void processInst(const InstPtr inst);
+
 	virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
 };
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp	2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp	2010-12-14 03:14:11 UTC (rev 54904)
@@ -28,6 +28,13 @@
 #include "disassembler.h"
 
 Scumm::v6::Scummv6Disassembler::Scummv6Disassembler(InstVec &insts) : SimpleDisassembler(insts) {
+	_instFactory.addEntry<Scummv6CondJumpInstruction>(kCondJumpInst);
+	_instFactory.addEntry<Scummv6JumpInstruction>(kJumpInst);
+	_instFactory.addEntry<Scummv6LoadInstruction>(kLoadInst);
+	_instFactory.addEntry<Scummv6StackInstruction>(kStackInst);
+	_instFactory.addEntry<Scummv6StoreInstruction>(kStoreInst);
+	_instFactory.addEntry<Scummv6ArrayOpInstruction>(kArrayOpInst);
+	_instFactory.addEntry<Scummv6IncDecInstruction>(kIncDecInst);
 }
 
 void Scumm::v6::Scummv6Disassembler::doDisassemble() throw(std::exception) {
@@ -63,114 +70,114 @@
 	}
 
 	START_OPCODES;
-		OPCODE(0x00, "pushByte", kLoadInstType, 1, "B");
-		OPCODE(0x01, "pushWord", kLoadInstType, 1, "s");
-		OPCODE(0x02, "pushByteVar", kLoadInstType, 1, "B");
-		OPCODE(0x03, "pushWordVar", kLoadInstType, 1, "w");
-		OPCODE(0x06, "byteArrayRead", kLoadInstType, 0, "B");
-		OPCODE(0x07, "wordArrayRead", kLoadInstType, 0, "w");
-		OPCODE(0x0A, "byteArrayIndexedRead", kLoadInstType, -1, "B");
-		OPCODE(0x0B, "wordArrayIndexedRead", kLoadInstType, -1, "w");
-		OPCODE(0x0C, "dup", kDupInstType, 1, "");
-		OPCODE_MD(0x0D, "not", kUnaryOpPreInstType, 0, "", "!");
-		OPCODE_MD(0x0E, "eq", kBinaryOpInstType, -1, "", "==");
-		OPCODE_MD(0x0F, "neq", kBinaryOpInstType, -1, "", "!=");
-		OPCODE_MD(0x10, "gt", kBinaryOpInstType, -1, "", ">");
-		OPCODE_MD(0x11, "lt", kBinaryOpInstType, -1, "", "<");
-		OPCODE_MD(0x12, "le", kBinaryOpInstType, -1, "", "<=");
-		OPCODE_MD(0x13, "ge", kBinaryOpInstType, -1, "", ">=");
-		OPCODE_MD(0x14, "add", kBinaryOpInstType, -1, "", "+");
-		OPCODE_MD(0x15, "sub", kBinaryOpInstType, -1, "", "-");
-		OPCODE_MD(0x16, "mul", kBinaryOpInstType, -1, "", "*");
-		OPCODE_MD(0x17, "div", kBinaryOpInstType, -1, "", "/");
-		OPCODE_MD(0x18, "land", kBinaryOpInstType, -1, "", "&&");
-		OPCODE_MD(0x19, "lor", kBinaryOpInstType, -1, "", "||");
-		OPCODE(0x1A, "pop", kStackInstType, -1, "");
-		OPCODE(0x42, "writeByteVar", kStoreInstType, -1, "B");
-		OPCODE(0x43, "writeWordVar", kStoreInstType, -1, "w");
-		OPCODE(0x46, "byteArrayWrite", kStoreInstType, -2, "B");
-		OPCODE(0x47, "wordArrayWrite", kStoreInstType, -2, "w");
-		OPCODE(0x4A, "byteArrayIndexedWrite", kStoreInstType, -3, "B");
-		OPCODE(0x4B, "wordArrayIndexedWrite", kStoreInstType, -3, "w");
-		OPCODE_MD(0x4E, "byteVarInc", kUnaryOpPostInstType, 0, "B", "++");
-		OPCODE_MD(0x4F, "wordVarInc", kUnaryOpPostInstType, 0, "w", "++");
-		OPCODE_MD(0x52, "byteArrayInc", kUnaryOpPostInstType, -1, "B", "++");
-		OPCODE_MD(0x53, "wordArrayInc", kUnaryOpPostInstType, -1, "w", "++");
-		OPCODE_MD(0x56, "byteVarDec", kUnaryOpPostInstType, 0, "B", "--");
-		OPCODE_MD(0x57, "wordVarDec", kUnaryOpPostInstType, 0, "w", "--");
-		OPCODE_MD(0x5A, "byteArrayDec", kUnaryOpPostInstType, -1, "B", "--");
-		OPCODE_MD(0x5B, "wordArrayDec", kUnaryOpPostInstType, -1, "w", "--");
-		OPCODE(0x5C, "jumpTrue", kCondJumpRelInstType, -1, "a");
-		OPCODE(0x5D, "jumpFalse", kCondJumpRelInstType, -1, "a");
-		OPCODE_MD(0x5E, "startScript", kSpecialCallInstType, 0x1020, "", "lpp"); // Variable stack arguments
-		OPCODE_MD(0x5F, "startScriptQuick", kSpecialCallInstType, 0x1010, "", "lp"); // Variable stack arguments
-		OPCODE_MD(0x60, "startObject", kSpecialCallInstType, 0x1030, "", "lppp"); // Variable stack arguments
-		OPCODE_MD(0x61, "drawObject", kSpecialCallInstType, -2, "", "pp");
-		OPCODE_MD(0x62, "drawObjectAt", kSpecialCallInstType, -3, "", "ppp");
-		OPCODE_MD(0x63, "drawBlastObject", kSpecialCallInstType, -5, "", "ppppp");
-		OPCODE_MD(0x64, "setBlastObjectWindow", kSpecialCallInstType, -4, "", "pppp");
-		OPCODE(0x65, "stopObjectCodeA", kSpecialCallInstType, 0, "");
-		OPCODE(0x66, "stopObjectCodeB", kSpecialCallInstType, 0, "");
-		OPCODE(0x67, "endCutscene", kSpecialCallInstType, 0, "");
-		OPCODE_MD(0x68, "beginCutscene", kSpecialCallInstType, 0x1000, "", "l"); // Variable stack arguments
-		OPCODE(0x69, "stopMusic", kSpecialCallInstType, 0, "");
-		OPCODE_MD(0x6A, "freezeUnfreeze", kSpecialCallInstType, -1, "", "p");
+		OPCODE(0x00, "pushByte", kLoadInst, 1, "B");
+		OPCODE(0x01, "pushWord", kLoadInst, 1, "s");
+		OPCODE(0x02, "pushByteVar", kLoadInst, 1, "B");
+		OPCODE(0x03, "pushWordVar", kLoadInst, 1, "w");
+		OPCODE(0x06, "byteArrayRead", kLoadInst, 0, "B");
+		OPCODE(0x07, "wordArrayRead", kLoadInst, 0, "w");
+		OPCODE(0x0A, "byteArrayIndexedRead", kLoadInst, -1, "B");
+		OPCODE(0x0B, "wordArrayIndexedRead", kLoadInst, -1, "w");
+		OPCODE(0x0C, "dup", kDupInst, 1, "");
+		OPCODE(0x0D, "not", kBoolNegateInst, 0, "");
+		OPCODE_MD(0x0E, "eq", kBinaryOpInst, -1, "", "==");
+		OPCODE_MD(0x0F, "neq", kBinaryOpInst, -1, "", "!=");
+		OPCODE_MD(0x10, "gt", kBinaryOpInst, -1, "", ">");
+		OPCODE_MD(0x11, "lt", kBinaryOpInst, -1, "", "<");
+		OPCODE_MD(0x12, "le", kBinaryOpInst, -1, "", "<=");
+		OPCODE_MD(0x13, "ge", kBinaryOpInst, -1, "", ">=");
+		OPCODE_MD(0x14, "add", kBinaryOpInst, -1, "", "+");
+		OPCODE_MD(0x15, "sub", kBinaryOpInst, -1, "", "-");
+		OPCODE_MD(0x16, "mul", kBinaryOpInst, -1, "", "*");
+		OPCODE_MD(0x17, "div", kBinaryOpInst, -1, "", "/");
+		OPCODE_MD(0x18, "land", kBinaryOpInst, -1, "", "&&");
+		OPCODE_MD(0x19, "lor", kBinaryOpInst, -1, "", "||");
+		OPCODE(0x1A, "pop", kStackInst, -1, "");
+		OPCODE(0x42, "writeByteVar", kStoreInst, -1, "B");
+		OPCODE(0x43, "writeWordVar", kStoreInst, -1, "w");
+		OPCODE(0x46, "byteArrayWrite", kStoreInst, -2, "B");
+		OPCODE(0x47, "wordArrayWrite", kStoreInst, -2, "w");
+		OPCODE(0x4A, "byteArrayIndexedWrite", kStoreInst, -3, "B");
+		OPCODE(0x4B, "wordArrayIndexedWrite", kStoreInst, -3, "w");
+		OPCODE_MD(0x4E, "byteVarInc", kIncDecInst, 0, "B", "++");
+		OPCODE_MD(0x4F, "wordVarInc", kIncDecInst, 0, "w", "++");
+		OPCODE_MD(0x52, "byteArrayInc", kIncDecInst, -1, "B", "++");
+		OPCODE_MD(0x53, "wordArrayInc", kIncDecInst, -1, "w", "++");
+		OPCODE_MD(0x56, "byteVarDec", kIncDecInst, 0, "B", "--");
+		OPCODE_MD(0x57, "wordVarDec", kIncDecInst, 0, "w", "--");
+		OPCODE_MD(0x5A, "byteArrayDec", kIncDecInst, -1, "B", "--");
+		OPCODE_MD(0x5B, "wordArrayDec", kIncDecInst, -1, "w", "--");
+		OPCODE(0x5C, "jumpTrue", kCondJumpInst, -1, "a");
+		OPCODE(0x5D, "jumpFalse", kCondJumpInst, -1, "a");
+		OPCODE_MD(0x5E, "startScript", kKernelCallInst, 0x1020, "", "lpp"); // Variable stack arguments
+		OPCODE_MD(0x5F, "startScriptQuick", kKernelCallInst, 0x1010, "", "lp"); // Variable stack arguments
+		OPCODE_MD(0x60, "startObject", kKernelCallInst, 0x1030, "", "lppp"); // Variable stack arguments
+		OPCODE_MD(0x61, "drawObject", kKernelCallInst, -2, "", "pp");
+		OPCODE_MD(0x62, "drawObjectAt", kKernelCallInst, -3, "", "ppp");
+		OPCODE_MD(0x63, "drawBlastObject", kKernelCallInst, -5, "", "ppppp");
+		OPCODE_MD(0x64, "setBlastObjectWindow", kKernelCallInst, -4, "", "pppp");
+		OPCODE(0x65, "stopObjectCodeA", kKernelCallInst, 0, "");
+		OPCODE(0x66, "stopObjectCodeB", kKernelCallInst, 0, "");
+		OPCODE(0x67, "endCutscene", kKernelCallInst, 0, "");
+		OPCODE_MD(0x68, "beginCutscene", kKernelCallInst, 0x1000, "", "l"); // Variable stack arguments
+		OPCODE(0x69, "stopMusic", kKernelCallInst, 0, "");
+		OPCODE_MD(0x6A, "freezeUnfreeze", kKernelCallInst, -1, "", "p");
 		START_SUBOPCODE_WITH_PREFIX(0x6B, "cursorCommand");
-			OPCODE(0x90, "cursorOn", kSpecialCallInstType, 0, "");
-			OPCODE(0x91, "cursorOff", kSpecialCallInstType, 0, "");
-			OPCODE(0x92, "userputOn", kSpecialCallInstType, 0, "");
-			OPCODE(0x93, "userputOff", kSpecialCallInstType, 0, "");
-			OPCODE(0x94, "softCursorOn", kSpecialCallInstType, 0, "");
-			OPCODE(0x95, "softCursorOff", kSpecialCallInstType, 0, "");
-			OPCODE(0x96, "softUserputOn", kSpecialCallInstType, 0, "");
-			OPCODE(0x97, "softUserputOff", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x99, "setCursorImg", kSpecialCallInstType, -2, "", "z");
-			OPCODE_MD(0x9A, "setCursorHotspot", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x9C, "initCharset", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x9D, "charsetColors", kSpecialCallInstType, 0x1000, "", "l"); // Variable stack arguments
-			OPCODE_MD(0xD6, "setCursorTransparency", kSpecialCallInstType, -1, "", "p");
+			OPCODE(0x90, "cursorOn", kKernelCallInst, 0, "");
+			OPCODE(0x91, "cursorOff", kKernelCallInst, 0, "");
+			OPCODE(0x92, "userputOn", kKernelCallInst, 0, "");
+			OPCODE(0x93, "userputOff", kKernelCallInst, 0, "");
+			OPCODE(0x94, "softCursorOn", kKernelCallInst, 0, "");
+			OPCODE(0x95, "softCursorOff", kKernelCallInst, 0, "");
+			OPCODE(0x96, "softUserputOn", kKernelCallInst, 0, "");
+			OPCODE(0x97, "softUserputOff", kKernelCallInst, 0, "");
+			OPCODE_MD(0x99, "setCursorImg", kKernelCallInst, -2, "", "z");
+			OPCODE_MD(0x9A, "setCursorHotspot", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x9C, "initCharset", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x9D, "charsetColors", kKernelCallInst, 0x1000, "", "l"); // Variable stack arguments
+			OPCODE_MD(0xD6, "setCursorTransparency", kKernelCallInst, -1, "", "p");
 		END_SUBOPCODE;
-		OPCODE(0x6C, "breakHere", kSpecialCallInstType, 0, "");
-		OPCODE_MD(0x6D, "ifClassOfIs", kSpecialCallInstType, 0x1011, "", "rlp"); // Variable stack arguments
-		OPCODE_MD(0x6E, "setClass", kSpecialCallInstType, 0x1010, "", "lp"); // Variable stack arguments
-		OPCODE_MD(0x6F, "getState", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x70, "setState", kSpecialCallInstType, -2, "", "pp");
-		OPCODE_MD(0x71, "setOwner", kSpecialCallInstType, -2, "", "pp");
-		OPCODE_MD(0x72, "getOwner", kSpecialCallInstType, 0, "", "rp");
-		OPCODE(0x73, "jump", kJumpRelInstType, 0, "a");
-		OPCODE_MD(0x74, "startSound", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x75, "stopSound", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x76, "startMusic", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x77, "stopObjectScript", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x78, "panCameraTo", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x79, "actorFollowCamera", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x7A, "setCameraAt", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x7B, "loadRoom", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x7C, "stopScript", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0x7D, "walkActorToObj", kSpecialCallInstType, -3, "", "ppp");
-		OPCODE_MD(0x7E, "walkActorTo", kSpecialCallInstType, -3, "", "ppp");
-		OPCODE_MD(0x7F, "putActorAtXY", kSpecialCallInstType, -4, "", "pppp");
-		OPCODE_MD(0x80, "putActorAtObject", kSpecialCallInstType, -3, "", "zp");
-		OPCODE_MD(0x81, "faceActor", kSpecialCallInstType, -2, "", "pp");
-		OPCODE_MD(0x82, "animateActor", kSpecialCallInstType, -2, "", "pp");
-		OPCODE_MD(0x83, "doSentence", kSpecialCallInstType, -4, "", "pppp");
-		OPCODE_MD(0x84, "pickupObject", kSpecialCallInstType, -2, "", "z");
-		OPCODE_MD(0x85, "loadRoomWithEgo", kSpecialCallInstType, -4, "", "ppz");
-		OPCODE_MD(0x87, "getRandomNumber", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x88, "getRandomNumberRange", kSpecialCallInstType, -1, "", "rpp");
-		OPCODE_MD(0x8A, "getActorMoving", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x8B, "isScriptRunning", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x8C, "getActorRoom", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x8D, "getObjectX", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x8E, "getObjectY", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x8F, "getObjectDir", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x90, "getActorWalkBox", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x91, "getActorCostume", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x92, "findInventory", kSpecialCallInstType, -1, "", "rpp");
-		OPCODE_MD(0x93, "getInventoryCount", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x94, "getVerbFromXY", kSpecialCallInstType, -1, "", "rpp");
+		OPCODE(0x6C, "breakHere", kKernelCallInst, 0, "");
+		OPCODE_MD(0x6D, "ifClassOfIs", kKernelCallInst, 0x1011, "", "rlp"); // Variable stack arguments
+		OPCODE_MD(0x6E, "setClass", kKernelCallInst, 0x1010, "", "lp"); // Variable stack arguments
+		OPCODE_MD(0x6F, "getState", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x70, "setState", kKernelCallInst, -2, "", "pp");
+		OPCODE_MD(0x71, "setOwner", kKernelCallInst, -2, "", "pp");
+		OPCODE_MD(0x72, "getOwner", kKernelCallInst, 0, "", "rp");
+		OPCODE(0x73, "jump", kJumpInst, 0, "a");
+		OPCODE_MD(0x74, "startSound", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x75, "stopSound", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x76, "startMusic", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x77, "stopObjectScript", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x78, "panCameraTo", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x79, "actorFollowCamera", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x7A, "setCameraAt", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x7B, "loadRoom", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x7C, "stopScript", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0x7D, "walkActorToObj", kKernelCallInst, -3, "", "ppp");
+		OPCODE_MD(0x7E, "walkActorTo", kKernelCallInst, -3, "", "ppp");
+		OPCODE_MD(0x7F, "putActorAtXY", kKernelCallInst, -4, "", "pppp");
+		OPCODE_MD(0x80, "putActorAtObject", kKernelCallInst, -3, "", "zp");
+		OPCODE_MD(0x81, "faceActor", kKernelCallInst, -2, "", "pp");
+		OPCODE_MD(0x82, "animateActor", kKernelCallInst, -2, "", "pp");
+		OPCODE_MD(0x83, "doSentence", kKernelCallInst, -4, "", "pppp");
+		OPCODE_MD(0x84, "pickupObject", kKernelCallInst, -2, "", "z");
+		OPCODE_MD(0x85, "loadRoomWithEgo", kKernelCallInst, -4, "", "ppz");
+		OPCODE_MD(0x87, "getRandomNumber", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x88, "getRandomNumberRange", kKernelCallInst, -1, "", "rpp");
+		OPCODE_MD(0x8A, "getActorMoving", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x8B, "isScriptRunning", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x8C, "getActorRoom", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x8D, "getObjectX", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x8E, "getObjectY", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x8F, "getObjectDir", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x90, "getActorWalkBox", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x91, "getActorCostume", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x92, "findInventory", kKernelCallInst, -1, "", "rpp");
+		OPCODE_MD(0x93, "getInventoryCount", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x94, "getVerbFromXY", kKernelCallInst, -1, "", "rpp");
 		OPCODE_BASE(0x95)
-			OPCODE_BODY("beginOverride", kSpecialCallInstType, 0, "", "");
+			OPCODE_BODY("beginOverride", kKernelCallInst, 0, "", "");
 			// FIXME/TODO: beginOverride skips the following jump - that jump is instead to a "finally" handler
 			// To simulate this, we simply skip the jump instruction, so the sequential order appears the same.
 			// Semantically, it would probably be more correct to model this as a conditional jump,
@@ -179,262 +186,262 @@
 			_f.seek(3, SEEK_CUR);
 			_address += 3;
 			OPCODE_END;
-		OPCODE(0x96, "endOverride", kSpecialCallInstType, 0, "");
-		OPCODE_MD(0x97, "setObjectName", kSpecialCallInstType, -1, "c", "ps");
-		OPCODE_MD(0x98, "isSoundRunning", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0x99, "setBoxFlags", kSpecialCallInstType, 0x1100, "", "pl"); // Variable stack arguments
-		OPCODE(0x9A, "createBoxMatrix", kSpecialCallInstType, 0, "");
+		OPCODE(0x96, "endOverride", kKernelCallInst, 0, "");
+		OPCODE_MD(0x97, "setObjectName", kKernelCallInst, -1, "c", "ps");
+		OPCODE_MD(0x98, "isSoundRunning", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0x99, "setBoxFlags", kKernelCallInst, 0x1100, "", "pl"); // Variable stack arguments
+		OPCODE(0x9A, "createBoxMatrix", kKernelCallInst, 0, "");
 		START_SUBOPCODE_WITH_PREFIX(0x9B, "resourceRoutines");
-			OPCODE_MD(0x64, "loadScript", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x65, "loadSound", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x66, "loadCostume", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x67, "loadRoom", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x68, "nukeScript", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x69, "nukeSound", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x6A, "nukeCostume", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x6B, "nukeRoom", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x6C, "lockScript", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x6D, "lockSound", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x6E, "lockCostume", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x6F, "lockRoom", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x70, "unlockScript", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x71, "unlockSound", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x72, "unlockCostume", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x73, "unlockRoom", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x75, "loadCharset", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x76, "nukeCharset", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x77, "loadFlObject", kSpecialCallInstType, -2, "", "pp");
+			OPCODE_MD(0x64, "loadScript", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x65, "loadSound", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x66, "loadCostume", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x67, "loadRoom", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x68, "nukeScript", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x69, "nukeSound", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x6A, "nukeCostume", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x6B, "nukeRoom", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x6C, "lockScript", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x6D, "lockSound", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x6E, "lockCostume", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x6F, "lockRoom", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x70, "unlockScript", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x71, "unlockSound", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x72, "unlockCostume", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x73, "unlockRoom", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x75, "loadCharset", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x76, "nukeCharset", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x77, "loadFlObject", kKernelCallInst, -2, "", "pp");
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0x9C, "roomOps");
-			OPCODE_MD(0xAC, "roomScroll", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0xAE, "setScreen", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0xAF, "setPalColor", kSpecialCallInstType, -4, "", "pppp");
-			OPCODE(0xB0, "shakeOn", kSpecialCallInstType, 0, "");
-			OPCODE(0xB1, "shakeOff", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0xB3, "darkenPalette", kSpecialCallInstType, -3, "", "ppp");
-			OPCODE_MD(0xB4, "saveLoadRoom", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0xB5, "screenEffect", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0xB6, "darkenPaletteRGB", kSpecialCallInstType, -5, "", "ppppp");
-			OPCODE_MD(0xB7, "setupShadowPalette", kSpecialCallInstType, -5, "", "ppppp");
-			OPCODE_MD(0xBA, "palManipulate", kSpecialCallInstType, -4, "", "pppp");
-			OPCODE_MD(0xBB, "colorCycleDelay", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0xD5, "setPalette", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0xDC, "copyPalColor", kSpecialCallInstType, -2, "", "pp");
+			OPCODE_MD(0xAC, "roomScroll", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0xAE, "setScreen", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0xAF, "setPalColor", kKernelCallInst, -4, "", "pppp");
+			OPCODE(0xB0, "shakeOn", kKernelCallInst, 0, "");
+			OPCODE(0xB1, "shakeOff", kKernelCallInst, 0, "");
+			OPCODE_MD(0xB3, "darkenPalette", kKernelCallInst, -3, "", "ppp");
+			OPCODE_MD(0xB4, "saveLoadRoom", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0xB5, "screenEffect", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0xB6, "darkenPaletteRGB", kKernelCallInst, -5, "", "ppppp");
+			OPCODE_MD(0xB7, "setupShadowPalette", kKernelCallInst, -5, "", "ppppp");
+			OPCODE_MD(0xBA, "palManipulate", kKernelCallInst, -4, "", "pppp");
+			OPCODE_MD(0xBB, "colorCycleDelay", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0xD5, "setPalette", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0xDC, "copyPalColor", kKernelCallInst, -2, "", "pp");
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0x9D, "actorOps");
-			OPCODE_MD(0x4C, "setCostume", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x4D, "setWalkSpeed", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x4E, "setSound", kSpecialCallInstType, 0x1000, "", "l"); // Variable stack arguments
-			OPCODE_MD(0x4F, "setWalkFrame", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x50, "setTalkFrame", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x51, "setStandFrame", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x52, "82?", kSpecialCallInstType, -3, "", "ppp");
-			OPCODE(0x53, "init", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x54, "setElevation", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x55, "setDefAnim", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x56, "setPalette", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x57, "setTalkColor", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x58, "setName", kSpecialCallInstType, 0, "c", "s");
-			OPCODE_MD(0x59, "setInitFrame", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x5B, "setWidth", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x5C, "setScale", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x5D, "setNeverZClip", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x5E, "setAlwaysZClip", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x5F, "setIgnoreBoxes", kSpecialCallInstType, 0, "");
-			OPCODE(0x60, "setFollowBoxes", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x61, "setAnimSpeed", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x62, "setShadowMode", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x63, "setTalkPos", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0xC5, "setCurActor", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0xC6, "setAnimVar", kSpecialCallInstType, -2, "", "pp");
-			OPCODE(0xD7, "setIgnoreTurnsOn", kSpecialCallInstType, 0, "");
-			OPCODE(0xD8, "setIgnoreTurnsOff", kSpecialCallInstType, 0, "");
-			OPCODE(0xD9, "initLittle", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0xE1, "setAlwaysZClip?", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0xE3, "setLayer", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0xE4, "setWalkScript", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0xE5, "setStanding", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0xE6, "setDirection", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0xE7, "turnToDirection", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0xE9, "freeze", kSpecialCallInstType, 0, "");
-			OPCODE(0xEA, "unfreeze", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0xEB, "setTalkScript", kSpecialCallInstType, -1, "", "p");
+			OPCODE_MD(0x4C, "setCostume", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x4D, "setWalkSpeed", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x4E, "setSound", kKernelCallInst, 0x1000, "", "l"); // Variable stack arguments
+			OPCODE_MD(0x4F, "setWalkFrame", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x50, "setTalkFrame", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x51, "setStandFrame", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x52, "82?", kKernelCallInst, -3, "", "ppp");
+			OPCODE(0x53, "init", kKernelCallInst, 0, "");
+			OPCODE_MD(0x54, "setElevation", kKernelCallInst, -1, "", "p");
+			OPCODE(0x55, "setDefAnim", kKernelCallInst, 0, "");
+			OPCODE_MD(0x56, "setPalette", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x57, "setTalkColor", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x58, "setName", kKernelCallInst, 0, "c", "s");
+			OPCODE_MD(0x59, "setInitFrame", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x5B, "setWidth", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x5C, "setScale", kKernelCallInst, -1, "", "p");
+			OPCODE(0x5D, "setNeverZClip", kKernelCallInst, 0, "");
+			OPCODE_MD(0x5E, "setAlwaysZClip", kKernelCallInst, -1, "", "p");
+			OPCODE(0x5F, "setIgnoreBoxes", kKernelCallInst, 0, "");
+			OPCODE(0x60, "setFollowBoxes", kKernelCallInst, 0, "");
+			OPCODE_MD(0x61, "setAnimSpeed", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x62, "setShadowMode", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x63, "setTalkPos", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0xC5, "setCurActor", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0xC6, "setAnimVar", kKernelCallInst, -2, "", "pp");
+			OPCODE(0xD7, "setIgnoreTurnsOn", kKernelCallInst, 0, "");
+			OPCODE(0xD8, "setIgnoreTurnsOff", kKernelCallInst, 0, "");
+			OPCODE(0xD9, "initLittle", kKernelCallInst, 0, "");
+			OPCODE_MD(0xE1, "setAlwaysZClip?", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0xE3, "setLayer", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0xE4, "setWalkScript", kKernelCallInst, -1, "", "p");
+			OPCODE(0xE5, "setStanding", kKernelCallInst, 0, "");
+			OPCODE_MD(0xE6, "setDirection", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0xE7, "turnToDirection", kKernelCallInst, -1, "", "p");
+			OPCODE(0xE9, "freeze", kKernelCallInst, 0, "");
+			OPCODE(0xEA, "unfreeze", kKernelCallInst, 0, "");
+			OPCODE_MD(0xEB, "setTalkScript", kKernelCallInst, -1, "", "p");
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0x9E, "verbOps");
-			OPCODE_MD(0x7C, "loadImg", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x7D, "loadString", kSpecialCallInstType, 0, "c", "s");
-			OPCODE_MD(0x7E, "setColor", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x7F, "setHiColor", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x80, "setXY", kSpecialCallInstType, -2, "", "pp");
-			OPCODE(0x81, "setOn", kSpecialCallInstType, 0, "");
-			OPCODE(0x82, "setOff", kSpecialCallInstType, 0, "");
-			OPCODE(0x83, "kill", kSpecialCallInstType, 0, "");
-			OPCODE(0x84, "init", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x85, "setDimColor", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x86, "setDimmed", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x87, "setKey", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x88, "setCenter", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x89, "setToString", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x8B, "setToObject", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x8C, "setBkColor", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0xC4, "setCurVerb", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0xFF, "redraw", kSpecialCallInstType, 0, "");
+			OPCODE_MD(0x7C, "loadImg", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x7D, "loadString", kKernelCallInst, 0, "c", "s");
+			OPCODE_MD(0x7E, "setColor", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x7F, "setHiColor", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x80, "setXY", kKernelCallInst, -2, "", "pp");
+			OPCODE(0x81, "setOn", kKernelCallInst, 0, "");
+			OPCODE(0x82, "setOff", kKernelCallInst, 0, "");
+			OPCODE(0x83, "kill", kKernelCallInst, 0, "");
+			OPCODE(0x84, "init", kKernelCallInst, 0, "");
+			OPCODE_MD(0x85, "setDimColor", kKernelCallInst, -1, "", "p");
+			OPCODE(0x86, "setDimmed", kKernelCallInst, 0, "");
+			OPCODE_MD(0x87, "setKey", kKernelCallInst, -1, "", "p");
+			OPCODE(0x88, "setCenter", kKernelCallInst, 0, "");
+			OPCODE_MD(0x89, "setToString", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x8B, "setToObject", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x8C, "setBkColor", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0xC4, "setCurVerb", kKernelCallInst, -1, "", "p");
+			OPCODE(0xFF, "redraw", kKernelCallInst, 0, "");
 		END_SUBOPCODE;
-		OPCODE_MD(0x9F, "getActorFromXY", kSpecialCallInstType, -1, "", "rpp");
-		OPCODE_MD(0xA0, "findObject", kSpecialCallInstType, -1, "", "rpp");
-		OPCODE_MD(0xA1, "pseudoRoom", kSpecialCallInstType, 0x1010, "", "lp"); // Variable stack arguments
-		OPCODE_MD(0xA2, "getActorElevation", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0xA3, "getVerbEntrypoint", kSpecialCallInstType, -1, "", "rpp");
+		OPCODE_MD(0x9F, "getActorFromXY", kKernelCallInst, -1, "", "rpp");
+		OPCODE_MD(0xA0, "findObject", kKernelCallInst, -1, "", "rpp");
+		OPCODE_MD(0xA1, "pseudoRoom", kKernelCallInst, 0x1010, "", "lp"); // Variable stack arguments
+		OPCODE_MD(0xA2, "getActorElevation", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0xA3, "getVerbEntrypoint", kKernelCallInst, -1, "", "rpp");
 		START_SUBOPCODE_WITH_PREFIX(0xA4, "arrayOps");
-			OPCODE_MD(0xCD, "assignString", kSpecialCallInstType, -1, "wc", "");
-			OPCODE_MD(0xD0, "assignIntList", kSpecialCallInstType, 0x1100, "w", ""); // Variable stack arguments
-			OPCODE_MD(0xD4, "assign2DimList", kSpecialCallInstType, 0x1100, "w", ""); // Variable stack arguments
+			OPCODE_MD(0xCD, "assignString", kArrayOpInst, -1, "wc", "");
+			OPCODE_MD(0xD0, "assignIntList", kArrayOpInst, 0x1100, "w", ""); // Variable stack arguments
+			OPCODE_MD(0xD4, "assign2DimList", kArrayOpInst, 0x1100, "w", ""); // Variable stack arguments
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0xA5, "saveRestoreVerbs");
-			OPCODE_MD(0x8D, "saveVerbs", kSpecialCallInstType, -3, "", "ppp");
-			OPCODE_MD(0x8E, "restoreVerbs", kSpecialCallInstType, -3, "", "ppp");
-			OPCODE_MD(0x8F, "deleteVerbs", kSpecialCallInstType, -3, "", "ppp");
+			OPCODE_MD(0x8D, "saveVerbs", kKernelCallInst, -3, "", "ppp");
+			OPCODE_MD(0x8E, "restoreVerbs", kKernelCallInst, -3, "", "ppp");
+			OPCODE_MD(0x8F, "deleteVerbs", kKernelCallInst, -3, "", "ppp");
 		END_SUBOPCODE;
-		OPCODE_MD(0xA6, "drawBox", kSpecialCallInstType, -5, "", "ppppp");
-		OPCODE(0xA7, "pop", kStackInstType, -1, "");
-		OPCODE_MD(0xA8, "getActorWidth", kSpecialCallInstType, 0, "", "rp");
+		OPCODE_MD(0xA6, "drawBox", kKernelCallInst, -5, "", "ppppp");
+		OPCODE(0xA7, "pop", kStackInst, -1, "");
+		OPCODE_MD(0xA8, "getActorWidth", kKernelCallInst, 0, "", "rp");
 		START_SUBOPCODE(0xA9); // wait
-			OPCODE_MD(0xA8, "waitForActor", kSpecialCallInstType, -1, "s", "pj");
-			OPCODE(0xA9, "waitForMessage", kSpecialCallInstType, 0, "");
-			OPCODE(0xAA, "waitForCamera", kSpecialCallInstType, 0, "");
-			OPCODE(0xAB, "waitForSentence", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0xE2, "waitUntilActorDrawn", kSpecialCallInstType, -1, "s", "pj");
-			OPCODE_MD(0xE8, "waitUntilActorTurned", kSpecialCallInstType, -1, "s", "pj");
+			OPCODE_MD(0xA8, "waitForActor", kKernelCallInst, -1, "s", "pj");
+			OPCODE(0xA9, "waitForMessage", kKernelCallInst, 0, "");
+			OPCODE(0xAA, "waitForCamera", kKernelCallInst, 0, "");
+			OPCODE(0xAB, "waitForSentence", kKernelCallInst, 0, "");
+			OPCODE_MD(0xE2, "waitUntilActorDrawn", kKernelCallInst, -1, "s", "pj");
+			OPCODE_MD(0xE8, "waitUntilActorTurned", kKernelCallInst, -1, "s", "pj");
 		END_SUBOPCODE;
-		OPCODE_MD(0xAA, "getActorScaleX", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0xAB, "getActorAnimCounter", kSpecialCallInstType, 0, "", "rp");
-		OPCODE_MD(0xAC, "soundKludge", kSpecialCallInstType, 0x1000, "", "l"); // Variable stack arguments
-		OPCODE_MD(0xAD, "isAnyOf", kSpecialCallInstType, 0x1011, "", "rlp"); // Variable stack arguments
+		OPCODE_MD(0xAA, "getActorScaleX", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0xAB, "getActorAnimCounter", kKernelCallInst, 0, "", "rp");
+		OPCODE_MD(0xAC, "soundKludge", kKernelCallInst, 0x1000, "", "l"); // Variable stack arguments
+		OPCODE_MD(0xAD, "isAnyOf", kKernelCallInst, 0x1011, "", "rlp"); // Variable stack arguments
 		START_SUBOPCODE_WITH_PREFIX(0xAE, "systemOps");
-			OPCODE(0x9E, "restartGame", kSpecialCallInstType, 0, "");
-			OPCODE(0x9F, "pauseGame", kSpecialCallInstType, 0, "");
-			OPCODE(0xA0, "shutDown", kSpecialCallInstType, 0, "");
+			OPCODE(0x9E, "restartGame", kKernelCallInst, 0, "");
+			OPCODE(0x9F, "pauseGame", kKernelCallInst, 0, "");
+			OPCODE(0xA0, "shutDown", kKernelCallInst, 0, "");
 		END_SUBOPCODE;
-		OPCODE_MD(0xAF, "isActorInBox", kSpecialCallInstType, -1, "", "rpp");
-		OPCODE_MD(0xB0, "delay", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0xB1, "delaySeconds", kSpecialCallInstType, -1, "", "p");
-		OPCODE_MD(0xB2, "delayMinutes", kSpecialCallInstType, -1, "", "p");
-		OPCODE(0xB3, "stopSentence", kSpecialCallInstType, 0, "");
+		OPCODE_MD(0xAF, "isActorInBox", kKernelCallInst, -1, "", "rpp");
+		OPCODE_MD(0xB0, "delay", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0xB1, "delaySeconds", kKernelCallInst, -1, "", "p");
+		OPCODE_MD(0xB2, "delayMinutes", kKernelCallInst, -1, "", "p");
+		OPCODE(0xB3, "stopSentence", kKernelCallInst, 0, "");
 		START_SUBOPCODE_WITH_PREFIX(0xB4, "printLine");
-			OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
-			OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
-			OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
-			OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
-			OPCODE(0xFE, "begin", kSpecialCallInstType, 0, "");
-			OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+			OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+			OPCODE(0x45, "center", kKernelCallInst, 0, "");
+			OPCODE(0x47, "left", kKernelCallInst, 0, "");
+			OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+			OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+			OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+			OPCODE(0xFE, "begin", kKernelCallInst, 0, "");
+			OPCODE(0xFF, "end", kKernelCallInst, 0, "");
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0xB5, "printText");
-			OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
-			OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
-			OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
-			OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
-			OPCODE(0xFE, "begin", kSpecialCallInstType, 0, "");
-			OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+			OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+			OPCODE(0x45, "center", kKernelCallInst, 0, "");
+			OPCODE(0x47, "left", kKernelCallInst, 0, "");
+			OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+			OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+			OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+			OPCODE(0xFE, "begin", kKernelCallInst, 0, "");
+			OPCODE(0xFF, "end", kKernelCallInst, 0, "");
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0xB6, "printDebug");
-			OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
-			OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
-			OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
-			OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
-			OPCODE(0xFE, "begin", kSpecialCallInstType, 0, "");
-			OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+			OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+			OPCODE(0x45, "center", kKernelCallInst, 0, "");
+			OPCODE(0x47, "left", kKernelCallInst, 0, "");
+			OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+			OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+			OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+			OPCODE(0xFE, "begin", kKernelCallInst, 0, "");
+			OPCODE(0xFF, "end", kKernelCallInst, 0, "");
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0xB7, "printSystem");
-			OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
-			OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
-			OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
-			OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
-			OPCODE(0xFE, "begin", kSpecialCallInstType, 0, "");
-			OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+			OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+			OPCODE(0x45, "center", kKernelCallInst, 0, "");
+			OPCODE(0x47, "left", kKernelCallInst, 0, "");
+			OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+			OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+			OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+			OPCODE(0xFE, "begin", kKernelCallInst, 0, "");
+			OPCODE(0xFF, "end", kKernelCallInst, 0, "");
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0xB8, "printActor");
-			OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
-			OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
-			OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
-			OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
-			OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
-			OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
-			OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
-			OPCODE_MD(0xFE, "begin", kSpecialCallInstType, -1, "", "p");
-			OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+			OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+			OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+			OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+			OPCODE(0x45, "center", kKernelCallInst, 0, "");
+			OPCODE(0x47, "left", kKernelCallInst, 0, "");
+			OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+			OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+			OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+			OPCODE_MD(0xFE, "begin", kKernelCallInst, -1, "", "p");
+			OPCODE(0xFF, "end", kKernelCallInst, 0, "");
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0xB9, "printEgo");

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list