changed encoding of segment 3 opcodes (increasing the number of opcodes, while reducing the width of the argument)

actorid
Marc Zinnschlag 15 years ago
parent 08d2b80434
commit b3cc3073a3

@ -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…
Cancel
Save