mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 16:09:39 +00:00
changed encoding of segment 3 opcodes (increasing the number of opcodes, while reducing the width of the argument)
This commit is contained in:
parent
08d2b80434
commit
b3cc3073a3
5 changed files with 93 additions and 89 deletions
|
@ -14,7 +14,7 @@ opcodes 0x200-0x3ff unused
|
||||||
|
|
||||||
Segment 3:
|
Segment 3:
|
||||||
(not implemented yet)
|
(not implemented yet)
|
||||||
opcodes 0x200-0x3ff unused
|
opcodes 0x20000-0x3ffff unused
|
||||||
|
|
||||||
Segment 4:
|
Segment 4:
|
||||||
(not implemented yet)
|
(not implemented yet)
|
||||||
|
|
|
@ -505,6 +505,11 @@ namespace Compiler
|
||||||
void message (CodeContainer& code, Literals& literals, const std::string& message,
|
void message (CodeContainer& code, Literals& literals, const std::string& message,
|
||||||
int buttons)
|
int buttons)
|
||||||
{
|
{
|
||||||
|
assert (buttons>=0);
|
||||||
|
|
||||||
|
if (buttons>=256)
|
||||||
|
throw std::runtime_error ("A message box can't have more than 255 buttons");
|
||||||
|
|
||||||
int index = literals.addString (message);
|
int index = literals.addString (message);
|
||||||
|
|
||||||
opPushInt (code, index);
|
opPushInt (code, index);
|
||||||
|
|
|
@ -36,8 +36,8 @@ namespace Compiler
|
||||||
|
|
||||||
inline Interpreter::Type_Code segment3 (unsigned int c, unsigned int arg0)
|
inline Interpreter::Type_Code segment3 (unsigned int c, unsigned int arg0)
|
||||||
{
|
{
|
||||||
assert (c<1024);
|
assert (c<262144);
|
||||||
return 0xc0000000 | (c<<20) | (arg0 & 0xffff);
|
return 0xc0000000 | (c<<8) | (arg0 & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Interpreter::Type_Code segment4 (unsigned int c, unsigned int arg0,
|
inline Interpreter::Type_Code segment4 (unsigned int c, unsigned int arg0,
|
||||||
|
@ -52,72 +52,71 @@ namespace Compiler
|
||||||
assert (c<67108864);
|
assert (c<67108864);
|
||||||
return 0xc8000000 | c;
|
return 0xc8000000 | c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushInt (CodeContainer& code, Literals& literals, int value);
|
void pushInt (CodeContainer& code, Literals& literals, int value);
|
||||||
|
|
||||||
void pushFloat (CodeContainer& code, Literals& literals, float value);
|
void pushFloat (CodeContainer& code, Literals& literals, float value);
|
||||||
|
|
||||||
void pushString (CodeContainer& code, Literals& literals, const std::string& value);
|
void pushString (CodeContainer& code, Literals& literals, const std::string& value);
|
||||||
|
|
||||||
void assignToLocal (CodeContainer& code, char localType,
|
void assignToLocal (CodeContainer& code, char localType,
|
||||||
int localIndex, const CodeContainer& value, char valueType);
|
int localIndex, const CodeContainer& value, char valueType);
|
||||||
|
|
||||||
void negate (CodeContainer& code, char valueType);
|
void negate (CodeContainer& code, char valueType);
|
||||||
|
|
||||||
void add (CodeContainer& code, char valueType1, char valueType2);
|
void add (CodeContainer& code, char valueType1, char valueType2);
|
||||||
|
|
||||||
void sub (CodeContainer& code, char valueType1, char valueType2);
|
void sub (CodeContainer& code, char valueType1, char valueType2);
|
||||||
|
|
||||||
void mul (CodeContainer& code, char valueType1, char valueType2);
|
void mul (CodeContainer& code, char valueType1, char valueType2);
|
||||||
|
|
||||||
void div (CodeContainer& code, char valueType1, char valueType2);
|
void div (CodeContainer& code, char valueType1, char valueType2);
|
||||||
|
|
||||||
void convert (CodeContainer& code, char fromType, char toType);
|
void convert (CodeContainer& code, char fromType, char toType);
|
||||||
|
|
||||||
void squareRoot (CodeContainer& code);
|
void squareRoot (CodeContainer& code);
|
||||||
|
|
||||||
void exit (CodeContainer& code);
|
void exit (CodeContainer& code);
|
||||||
|
|
||||||
void message (CodeContainer& code, Literals& literals, const std::string& message,
|
void message (CodeContainer& code, Literals& literals, const std::string& message,
|
||||||
int buttons);
|
int buttons);
|
||||||
|
|
||||||
void fetchLocal (CodeContainer& code, char localType, int localIndex);
|
void fetchLocal (CodeContainer& code, char localType, int localIndex);
|
||||||
|
|
||||||
void jump (CodeContainer& code, int offset);
|
void jump (CodeContainer& code, int offset);
|
||||||
|
|
||||||
void jumpOnZero (CodeContainer& code, int offset);
|
void jumpOnZero (CodeContainer& code, int offset);
|
||||||
|
|
||||||
void jumpOnNonZero (CodeContainer& code, int offset);
|
void jumpOnNonZero (CodeContainer& code, int offset);
|
||||||
|
|
||||||
void compare (CodeContainer& code, char op, char valueType1, char valueType2);
|
void compare (CodeContainer& code, char op, char valueType1, char valueType2);
|
||||||
|
|
||||||
void menuMode (CodeContainer& code);
|
void menuMode (CodeContainer& code);
|
||||||
|
|
||||||
void assignToGlobal (CodeContainer& code, Literals& literals, char localType,
|
void assignToGlobal (CodeContainer& code, Literals& literals, char localType,
|
||||||
const std::string& name, const CodeContainer& value, char valueType);
|
const std::string& name, const CodeContainer& value, char valueType);
|
||||||
|
|
||||||
void fetchGlobal (CodeContainer& code, Literals& literals, char localType,
|
void fetchGlobal (CodeContainer& code, Literals& literals, char localType,
|
||||||
const std::string& name);
|
const std::string& name);
|
||||||
|
|
||||||
void random (CodeContainer& code);
|
void random (CodeContainer& code);
|
||||||
|
|
||||||
void scriptRunning (CodeContainer& code);
|
void scriptRunning (CodeContainer& code);
|
||||||
|
|
||||||
void startScript (CodeContainer& code);
|
void startScript (CodeContainer& code);
|
||||||
|
|
||||||
void stopScript (CodeContainer& code);
|
void stopScript (CodeContainer& code);
|
||||||
|
|
||||||
void getDistance (CodeContainer& code, Literals& literals, const std::string id);
|
void getDistance (CodeContainer& code, Literals& literals, const std::string id);
|
||||||
|
|
||||||
void getSecondsPassed (CodeContainer& code);
|
void getSecondsPassed (CodeContainer& code);
|
||||||
|
|
||||||
void getDisabled (CodeContainer& code, Literals& literals, const std::string id);
|
void getDisabled (CodeContainer& code, Literals& literals, const std::string id);
|
||||||
|
|
||||||
void enable (CodeContainer& code, Literals& literals, const std::string id);
|
void enable (CodeContainer& code, Literals& literals, const std::string id);
|
||||||
|
|
||||||
void disable (CodeContainer& code, Literals& literals, const std::string id);
|
void disable (CodeContainer& code, Literals& literals, const std::string id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ Code bit-patterns:
|
||||||
00ccccccAAAAAAAAAAAAAAAAAAAAAAAA segment 0: 64 opcodes, 1 24-bit argument
|
00ccccccAAAAAAAAAAAAAAAAAAAAAAAA segment 0: 64 opcodes, 1 24-bit argument
|
||||||
01ccccccAAAAAAAAAAAABBBBBBBBBBBB segment 1: 64 opcodes, 2 12-bit arguments
|
01ccccccAAAAAAAAAAAABBBBBBBBBBBB segment 1: 64 opcodes, 2 12-bit arguments
|
||||||
10ccccccccccAAAAAAAAAAAAAAAAAAAA segment 2: 1024 opcodes, 1 20-bit argument
|
10ccccccccccAAAAAAAAAAAAAAAAAAAA segment 2: 1024 opcodes, 1 20-bit argument
|
||||||
110000ccccccccccAAAAAAAAAAAAAAAA segment 3: 1024 opcodes, 1 16-bit argument
|
110000ccccccccccccccccccAAAAAAAA segment 3: 262144 opcodes, 1 8-bit argument
|
||||||
110001ccccccccccAAAAAAAABBBBBBBB segment 4: 1024 opcodes, 2 8-bit arguments
|
110001ccccccccccAAAAAAAABBBBBBBB segment 4: 1024 opcodes, 2 8-bit arguments
|
||||||
110010cccccccccccccccccccccccccc segment 5: 67108864 opcodes, no arguments
|
110010cccccccccccccccccccccccccc segment 5: 67108864 opcodes, no arguments
|
||||||
other bit-patterns reserved
|
other bit-patterns reserved
|
||||||
|
@ -50,8 +50,8 @@ op 0: show message box with message string literal index in stack[0];
|
||||||
additional arguments (if any) in stack[arg0+n]..stack[arg0+1];
|
additional arguments (if any) in stack[arg0+n]..stack[arg0+1];
|
||||||
n is determined according to the message string
|
n is determined according to the message string
|
||||||
all arguments are removed from stack
|
all arguments are removed from stack
|
||||||
opcodes 1-511 unused
|
opcodes 1-131071 unused
|
||||||
opcodes 512-1023 reserved for extensions
|
opcodes 131072-262143 reserved for extensions
|
||||||
|
|
||||||
Segment 4:
|
Segment 4:
|
||||||
opcodes 0-511 unused
|
opcodes 0-511 unused
|
||||||
|
|
|
@ -13,131 +13,131 @@ namespace Interpreter
|
||||||
void Interpreter::execute (Type_Code code)
|
void Interpreter::execute (Type_Code code)
|
||||||
{
|
{
|
||||||
unsigned int segSpec = code>>30;
|
unsigned int segSpec = code>>30;
|
||||||
|
|
||||||
switch (segSpec)
|
switch (segSpec)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
int opcode = code>>24;
|
int opcode = code>>24;
|
||||||
unsigned int arg0 = code & 0xffffff;
|
unsigned int arg0 = code & 0xffffff;
|
||||||
|
|
||||||
std::map<int, Opcode1 *>::iterator iter = mSegment0.find (opcode);
|
std::map<int, Opcode1 *>::iterator iter = mSegment0.find (opcode);
|
||||||
|
|
||||||
if (iter==mSegment0.end())
|
if (iter==mSegment0.end())
|
||||||
abortUnknownCode (0, opcode);
|
abortUnknownCode (0, opcode);
|
||||||
|
|
||||||
iter->second->execute (mRuntime, arg0);
|
iter->second->execute (mRuntime, arg0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
int opcode = (code>>24) & 0x3f;
|
int opcode = (code>>24) & 0x3f;
|
||||||
unsigned int arg0 = (code>>16) & 0xfff;
|
unsigned int arg0 = (code>>16) & 0xfff;
|
||||||
unsigned int arg1 = code & 0xfff;
|
unsigned int arg1 = code & 0xfff;
|
||||||
|
|
||||||
std::map<int, Opcode2 *>::iterator iter = mSegment1.find (opcode);
|
std::map<int, Opcode2 *>::iterator iter = mSegment1.find (opcode);
|
||||||
|
|
||||||
if (iter==mSegment1.end())
|
if (iter==mSegment1.end())
|
||||||
abortUnknownCode (1, opcode);
|
abortUnknownCode (1, opcode);
|
||||||
|
|
||||||
iter->second->execute (mRuntime, arg0, arg1);
|
iter->second->execute (mRuntime, arg0, arg1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
int opcode = (code>>20) & 0x3ff;
|
int opcode = (code>>20) & 0x3ff;
|
||||||
unsigned int arg0 = code & 0xfffff;
|
unsigned int arg0 = code & 0xfffff;
|
||||||
|
|
||||||
std::map<int, Opcode1 *>::iterator iter = mSegment2.find (opcode);
|
std::map<int, Opcode1 *>::iterator iter = mSegment2.find (opcode);
|
||||||
|
|
||||||
if (iter==mSegment2.end())
|
if (iter==mSegment2.end())
|
||||||
abortUnknownCode (2, opcode);
|
abortUnknownCode (2, opcode);
|
||||||
|
|
||||||
iter->second->execute (mRuntime, arg0);
|
iter->second->execute (mRuntime, arg0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
segSpec = code>>26;
|
segSpec = code>>26;
|
||||||
|
|
||||||
switch (segSpec)
|
switch (segSpec)
|
||||||
{
|
{
|
||||||
case 0x30:
|
case 0x30:
|
||||||
{
|
{
|
||||||
int opcode = (code>>16) & 0x3ff;
|
int opcode = (code>>8) & 0x3ffff;
|
||||||
unsigned int arg0 = code & 0xffff;
|
unsigned int arg0 = code & 0xff;
|
||||||
|
|
||||||
std::map<int, Opcode1 *>::iterator iter = mSegment3.find (opcode);
|
std::map<int, Opcode1 *>::iterator iter = mSegment3.find (opcode);
|
||||||
|
|
||||||
if (iter==mSegment3.end())
|
if (iter==mSegment3.end())
|
||||||
abortUnknownCode (3, opcode);
|
abortUnknownCode (3, opcode);
|
||||||
|
|
||||||
iter->second->execute (mRuntime, arg0);
|
iter->second->execute (mRuntime, arg0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x31:
|
case 0x31:
|
||||||
{
|
{
|
||||||
int opcode = (code>>16) & 0x3ff;
|
int opcode = (code>>16) & 0x3ff;
|
||||||
unsigned int arg0 = (code>>8) & 0xff;
|
unsigned int arg0 = (code>>8) & 0xff;
|
||||||
unsigned int arg1 = code & 0xff;
|
unsigned int arg1 = code & 0xff;
|
||||||
|
|
||||||
std::map<int, Opcode2 *>::iterator iter = mSegment4.find (opcode);
|
std::map<int, Opcode2 *>::iterator iter = mSegment4.find (opcode);
|
||||||
|
|
||||||
if (iter==mSegment4.end())
|
if (iter==mSegment4.end())
|
||||||
abortUnknownCode (4, opcode);
|
abortUnknownCode (4, opcode);
|
||||||
|
|
||||||
iter->second->execute (mRuntime, arg0, arg1);
|
iter->second->execute (mRuntime, arg0, arg1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x32:
|
case 0x32:
|
||||||
{
|
{
|
||||||
int opcode = code & 0x3ffffff;
|
int opcode = code & 0x3ffffff;
|
||||||
|
|
||||||
std::map<int, Opcode0 *>::iterator iter = mSegment5.find (opcode);
|
std::map<int, Opcode0 *>::iterator iter = mSegment5.find (opcode);
|
||||||
|
|
||||||
if (iter==mSegment5.end())
|
if (iter==mSegment5.end())
|
||||||
abortUnknownCode (5, opcode);
|
abortUnknownCode (5, opcode);
|
||||||
|
|
||||||
iter->second->execute (mRuntime);
|
iter->second->execute (mRuntime);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abortUnknownSegment (code);
|
abortUnknownSegment (code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::abortUnknownCode (int segment, int opcode)
|
void Interpreter::abortUnknownCode (int segment, int opcode)
|
||||||
{
|
{
|
||||||
std::ostringstream error;
|
std::ostringstream error;
|
||||||
|
|
||||||
error << "unknown opcode " << opcode << " in segment " << segment;
|
error << "unknown opcode " << opcode << " in segment " << segment;
|
||||||
|
|
||||||
throw std::runtime_error (error.str());
|
throw std::runtime_error (error.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::abortUnknownSegment (Type_Code code)
|
void Interpreter::abortUnknownSegment (Type_Code code)
|
||||||
{
|
{
|
||||||
std::ostringstream error;
|
std::ostringstream error;
|
||||||
|
|
||||||
error << "opcode outside of the allocated segment range: " << code;
|
error << "opcode outside of the allocated segment range: " << code;
|
||||||
|
|
||||||
throw std::runtime_error (error.str());
|
throw std::runtime_error (error.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
Interpreter::Interpreter (Context& context)
|
Interpreter::Interpreter (Context& context)
|
||||||
: mRuntime (context)
|
: mRuntime (context)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Interpreter::~Interpreter()
|
Interpreter::~Interpreter()
|
||||||
{
|
{
|
||||||
for (std::map<int, Opcode1 *>::iterator iter (mSegment0.begin());
|
for (std::map<int, Opcode1 *>::iterator iter (mSegment0.begin());
|
||||||
|
@ -159,12 +159,12 @@ namespace Interpreter
|
||||||
for (std::map<int, Opcode2 *>::iterator iter (mSegment4.begin());
|
for (std::map<int, Opcode2 *>::iterator iter (mSegment4.begin());
|
||||||
iter!=mSegment4.end(); ++iter)
|
iter!=mSegment4.end(); ++iter)
|
||||||
delete iter->second;
|
delete iter->second;
|
||||||
|
|
||||||
for (std::map<int, Opcode0 *>::iterator iter (mSegment5.begin());
|
for (std::map<int, Opcode0 *>::iterator iter (mSegment5.begin());
|
||||||
iter!=mSegment5.end(); ++iter)
|
iter!=mSegment5.end(); ++iter)
|
||||||
delete iter->second;
|
delete iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::installSegment0 (int code, Opcode1 *opcode)
|
void Interpreter::installSegment0 (int code, Opcode1 *opcode)
|
||||||
{
|
{
|
||||||
mSegment0.insert (std::make_pair (code, opcode));
|
mSegment0.insert (std::make_pair (code, opcode));
|
||||||
|
@ -194,24 +194,24 @@ namespace Interpreter
|
||||||
{
|
{
|
||||||
mSegment5.insert (std::make_pair (code, opcode));
|
mSegment5.insert (std::make_pair (code, opcode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::run (const Type_Code *code, int codeSize)
|
void Interpreter::run (const Type_Code *code, int codeSize)
|
||||||
{
|
{
|
||||||
assert (codeSize>=4);
|
assert (codeSize>=4);
|
||||||
|
|
||||||
mRuntime.configure (code, codeSize);
|
mRuntime.configure (code, codeSize);
|
||||||
|
|
||||||
int opcodes = static_cast<int> (code[0]);
|
int opcodes = static_cast<int> (code[0]);
|
||||||
|
|
||||||
const Type_Code *codeBlock = code + 4;
|
const Type_Code *codeBlock = code + 4;
|
||||||
|
|
||||||
while (mRuntime.getPC()>=0 && mRuntime.getPC()<opcodes)
|
while (mRuntime.getPC()>=0 && mRuntime.getPC()<opcodes)
|
||||||
{
|
{
|
||||||
Type_Code code = codeBlock[mRuntime.getPC()];
|
Type_Code code = codeBlock[mRuntime.getPC()];
|
||||||
mRuntime.setPC (mRuntime.getPC()+1);
|
mRuntime.setPC (mRuntime.getPC()+1);
|
||||||
execute (code);
|
execute (code);
|
||||||
}
|
}
|
||||||
|
|
||||||
mRuntime.clear();
|
mRuntime.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue