[Scummvm-cvs-logs] SF.net SVN: scummvm:[47956] scummvm/trunk/engines/sci/engine
fingolfin at users.sourceforge.net
fingolfin at users.sourceforge.net
Sun Feb 7 13:13:59 CET 2010
Revision: 47956
http://scummvm.svn.sourceforge.net/scummvm/?rev=47956&view=rev
Author: fingolfin
Date: 2010-02-07 12:13:59 +0000 (Sun, 07 Feb 2010)
Log Message:
-----------
SCI: Add function readPMachineInstruction()
Modified Paths:
--------------
scummvm/trunk/engines/sci/engine/vm.cpp
scummvm/trunk/engines/sci/engine/vm.h
Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp 2010-02-07 12:13:34 UTC (rev 47955)
+++ scummvm/trunk/engines/sci/engine/vm.cpp 2010-02-07 12:13:59 UTC (rev 47956)
@@ -584,6 +584,75 @@
static const byte _fake_return_buffer[2] = {op_ret << 1, op_ret << 1};
+
+int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4]) {
+ uint offset = 0;
+ extOpcode = src[offset++]; // Get "extended" opcode (lower bit has special meaning)
+ const byte opnumber = extOpcode >> 1; // get the actual opcode
+
+ memset(opparams, 0, sizeof(opparams));
+
+ for (int i = 0; g_opcode_formats[opnumber][i]; ++i) {
+ //printf("Opcode: 0x%x, Opnumber: 0x%x, temp: %d\n", opcode, opnumber, temp);
+ assert(i < 4);
+ switch (g_opcode_formats[opnumber][i]) {
+
+ case Script_Byte:
+ opparams[i] = src[offset++];
+ break;
+ case Script_SByte:
+ opparams[i] = (int8)src[offset++];
+ break;
+
+ case Script_Word:
+ opparams[i] = READ_LE_UINT16(src + offset);
+ offset += 2;
+ break;
+ case Script_SWord:
+ opparams[i] = (int16)READ_LE_UINT16(src + offset);
+ offset += 2;
+ break;
+
+ case Script_Variable:
+ case Script_Property:
+
+ case Script_Local:
+ case Script_Temp:
+ case Script_Global:
+ case Script_Param:
+
+ case Script_Offset:
+ if (extOpcode & 1) {
+ opparams[i] = src[offset++];
+ } else {
+ opparams[i] = READ_LE_UINT16(src + offset);
+ offset += 2;
+ }
+ break;
+
+ case Script_SVariable:
+ case Script_SRelative:
+ if (extOpcode & 1) {
+ opparams[i] = (int8)src[offset++];
+ } else {
+ opparams[i] = (int16)READ_LE_UINT16(src + offset);
+ offset += 2;
+ }
+ break;
+
+ case Script_None:
+ case Script_End:
+ break;
+
+ case Script_Invalid:
+ default:
+ error("opcode %02x: Invalid", extOpcode);
+ }
+ }
+
+ return offset;
+}
+
void run_vm(EngineState *s, bool restoring) {
assert(s);
@@ -635,8 +704,6 @@
s->_executionStackPosChanged = true; // Force initialization
while (1) {
- byte opcode;
- byte opnumber;
int var_type; // See description below
int var_number;
@@ -720,57 +787,11 @@
error("run_vm(): program counter gone astray");
#endif
- opcode = GET_OP_BYTE(); // Get opcode
+ // Get opcode
+ byte opcode;
+ scriptState.xs->addr.pc.offset += readPMachineInstruction(code_buf + scriptState.xs->addr.pc.offset, opcode, opparams);
+ const byte opnumber = opcode >> 1;
- opnumber = opcode >> 1;
-
- for (temp = 0; g_opcode_formats[opnumber][temp]; temp++) {
- //printf("Opcode: 0x%x, Opnumber: 0x%x, temp: %d\n", opcode, opnumber, temp);
- switch (g_opcode_formats[opnumber][temp]) {
-
- case Script_Byte:
- opparams[temp] = GET_OP_BYTE();
- break;
- case Script_SByte:
- opparams[temp] = GET_OP_SIGNED_BYTE();
- break;
-
- case Script_Word:
- opparams[temp] = GET_OP_WORD();
- break;
- case Script_SWord:
- opparams[temp] = GET_OP_SIGNED_WORD();
- break;
-
- case Script_Variable:
- case Script_Property:
-
- case Script_Local:
- case Script_Temp:
- case Script_Global:
- case Script_Param:
- opparams[temp] = GET_OP_FLEX();
- break;
-
- case Script_SVariable:
- case Script_SRelative:
- opparams[temp] = GET_OP_SIGNED_FLEX();
- break;
-
- case Script_Offset:
- opparams[temp] = GET_OP_FLEX();
- break;
-
- case Script_None:
- case Script_End:
- break;
-
- case Script_Invalid:
- default:
- error("opcode %02x: Invalid", opcode);
- }
- }
-
switch (opnumber) {
case op_bnot: // 0x00 (00)
Modified: scummvm/trunk/engines/sci/engine/vm.h
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.h 2010-02-07 12:13:34 UTC (rev 47955)
+++ scummvm/trunk/engines/sci/engine/vm.h 2010-02-07 12:13:59 UTC (rev 47956)
@@ -523,6 +523,24 @@
*/
void shrink_execution_stack(EngineState *s, uint size);
+/**
+ * Read a PMachine instruction from a memory buffer and return its length.
+ *
+ * @param[in] src address from which to start parsing
+ * @param[out] extOpcode "extended" opcode of the parsed instruction
+ * @param[out] opparams parameter for the parsed instruction
+ * @return the length in bytes of the instruction
+ *
+ * @todo How about changing opparams from int16 to int / int32 to preserve
+ * unsigned 16bit words as read for Script_Word? In the past, this
+ * was irrelevant as only a debug opcode used Script_Word. But with
+ * SCI32 we are now using Script_Word for more opcodes. Maybe this is
+ * just a mistake and those opcodes should used Script_SWord -- but if
+ * not then we definitely should change this to int, else we might run
+ * into trouble if we encounter high value words. *If* those exist at all.
+ */
+int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4]);
+
} // End of namespace Sci
#endif // SCI_ENGINE_VM_H
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