[Scummvm-cvs-logs] SF.net SVN: scummvm:[51452] tools/branches/gsoc2010-decompiler/decompiler/ kyra/disassembler.cpp

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Thu Jul 29 03:05:58 CEST 2010


Revision: 51452
          http://scummvm.svn.sourceforge.net/scummvm/?rev=51452&view=rev
Author:   pidgeot
Date:     2010-07-29 01:05:58 +0000 (Thu, 29 Jul 2010)

Log Message:
-----------
Preliminary KYRA disassembler

Still a few things to add, like function detection and calls, but this
can at least decode the individual instructions.

Modified Paths:
--------------
    tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-07-29 01:05:11 UTC (rev 51451)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-07-29 01:05:58 UTC (rev 51452)
@@ -29,7 +29,7 @@
 	_data = NULL;
 }
 
-Kyra::Disassembler::Disassembler(Engine *engine) : _engine(engine) {
+Kyra::Disassembler::Disassembler(Engine *engine) : ::Disassembler(), _engine(engine) {
 }
 
 Kyra::Disassembler::~Disassembler() {
@@ -99,5 +99,126 @@
 #undef posString
 
 	// Disassemble
-	// TODO
+	uint16 numInsts = _dataChunk._size / 2;
+	for (uint16 i = 0; i < numInsts; ++i) {
+		uint16 address = i*2;
+		uint16 code = READ_BE_UINT16(&((uint16 *)_dataChunk._data)[i]);
+		int16 opcode = (code >> 8) & 0x1F;
+		int16 parameter;
+
+		if (code & 0x8000) {
+			opcode = 0;
+			parameter = code & 0x7FFF;
+		} else if (code & 0x4000) {
+			parameter = (int8)(code);
+		} else if (code & 0x2000) {
+			i++;
+			parameter = READ_BE_UINT16(&((uint16 *)_dataChunk._data)[i]);
+		} else {
+			parameter = 0;
+		}
+
+#define ADD_INST _insts.push_back(Instruction());
+#define LAST_INST (_insts[_insts.size()-1])
+#define OPCODE_MD(name, category, stackChange, codeGenData) \
+		ADD_INST; \
+		LAST_INST._opcode = opcode; \
+		LAST_INST._address = address; \
+		LAST_INST._stackChange = stackChange; \
+		LAST_INST._name = name; \
+		LAST_INST._type = category; \
+		LAST_INST._codeGenData = codeGenData; \
+		{ \
+			Parameter p; \
+			p._type = kShort; \
+			p._value = parameter; \
+			LAST_INST._params.push_back(p);\
+		}
+#define OPCODE(name, category, stackChange) OPCODE_MD(name, category, stackChange, "");
+
+		// TOOD: Add metadata where applicable
+		switch(opcode) {
+		case 0:
+			OPCODE("jumpTo", kJump, 0);
+			break;
+		case 1:
+			OPCODE("setRetValue", kStore, 0);
+			break;
+		case 2:
+			if (parameter == 0) {
+				OPCODE("pushRet", kLoad, 1);
+			} else if (parameter == 1) {
+				OPCODE("pushPos", kSpecial, 2); // Sets up function call?
+			} else {
+				// Error: invalid parameter halts execution
+			}
+			break;
+		case 3:
+		case 4:
+			OPCODE("push", kLoad, 1);
+			break;
+		case 5:
+			OPCODE("pushVar", kLoad, 1);
+			break;
+		case 6:
+			OPCODE("pushBPNeg", kLoad, 1);
+			break;
+		case 7:
+			OPCODE("pushBPAdd", kLoad, 1);
+			break;
+		case 8:
+			if (parameter == 0) {
+				OPCODE("popRet", kStore, -1);
+			} else if (parameter == 1) {
+				OPCODE("popPos", kSpecial, -2); // Returns from function call?
+			} else {
+				// Error: invalid parameter halts execution
+			}
+			break;
+		case 9:
+			OPCODE("popVar", kStore, 1);
+			break;
+		case 10:
+			OPCODE("popBPNeg", kStore, 1);
+			break;
+		case 11:
+			OPCODE("popBPAdd", kStore, 1);
+			break;
+		case 12:
+			OPCODE("addSP", kStack, -parameter);
+			break;
+		case 13:
+			OPCODE("subSP", kStack, parameter);
+			break;
+		case 14:
+			OPCODE("execOpcode", kSpecial, 0); // TODO: Full details of opcode
+			break;
+		case 15:
+			OPCODE("ifNotJmp", kCondJump, -1);
+			break;
+		case 16:
+			if (parameter == 0) {
+				OPCODE_MD("boolCast", kUnaryOp, 0, "(bool)");
+			} else if (parameter == 1) {
+				OPCODE_MD("arithmeticNegate", kUnaryOp, 0, "-");
+			} else if (parameter == 2) {
+				OPCODE_MD("bitwiseNegate", kUnaryOp, 0, "~");
+			} else {
+				// Error: invalid parameter halts execution
+			}
+			break;
+		case 17:
+			OPCODE("eval", kBinaryOp, -1); // TODO: Full details of opcode
+			break;
+		case 18:
+			OPCODE("setRetAndJmp", kSpecial, -2); // Returns from function call?
+			break;
+		default:
+			throw UnknownOpcodeException(i*2, code);
+		}
+#undef OPCODE
+#undef OPCODE_MD
+#undef LAST_INST
+#undef ADD_INST
+	}
 }


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