mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-09-06 22:10:40 +02:00
Fixes invalid text pasting, Adds API to VM, allow program loading in Lua and assigning to update function
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include "dialogues/TextPrompt.h"
|
#include "dialogues/TextPrompt.h"
|
||||||
#include "dialogues/ConfirmPrompt.h"
|
#include "dialogues/ConfirmPrompt.h"
|
||||||
#include "simulation/Simulation.h"
|
#include "simulation/Simulation.h"
|
||||||
|
#include "virtualmachine/VirtualMachine.h"
|
||||||
#include "game/GameModel.h"
|
#include "game/GameModel.h"
|
||||||
#include "LuaScriptHelper.h"
|
#include "LuaScriptHelper.h"
|
||||||
#include "client/HTTP.h"
|
#include "client/HTTP.h"
|
||||||
@@ -63,6 +64,7 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
|
|||||||
initInterfaceAPI();
|
initInterfaceAPI();
|
||||||
initRendererAPI();
|
initRendererAPI();
|
||||||
initElementsAPI();
|
initElementsAPI();
|
||||||
|
initVirtualMachineAPI();
|
||||||
|
|
||||||
//Old TPT API
|
//Old TPT API
|
||||||
int i = 0, j;
|
int i = 0, j;
|
||||||
@@ -651,6 +653,42 @@ void LuaScriptInterface::initElementsAPI()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm::VirtualMachine * LuaScriptInterface::updateVirtualMachines[PT_NUM];
|
||||||
|
|
||||||
|
int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS)
|
||||||
|
{
|
||||||
|
vm::VirtualMachine * vMachine = updateVirtualMachines[parts[i].type];
|
||||||
|
|
||||||
|
vm::word w;
|
||||||
|
int argAddr = 0, argCount = 5;
|
||||||
|
vMachine->sim = sim;
|
||||||
|
|
||||||
|
/* Set up call. */
|
||||||
|
vMachine->OpPUSH(w); //Pointless null in stack
|
||||||
|
w.int4 = (argCount + 2) * sizeof(vm::word);
|
||||||
|
vMachine->OpENTER(w);
|
||||||
|
argAddr = 8;
|
||||||
|
|
||||||
|
//Arguments
|
||||||
|
w.int4 = i; vMachine->Marshal(argAddr, w); argAddr += 4;
|
||||||
|
w.int4 = x; vMachine->Marshal(argAddr, w); argAddr += 4;
|
||||||
|
w.int4 = y; vMachine->Marshal(argAddr, w); argAddr += 4;
|
||||||
|
w.int4 = nt; vMachine->Marshal(argAddr, w); argAddr += 4;
|
||||||
|
w.int4 = surround_space; vMachine->Marshal(argAddr, w); argAddr += 4;
|
||||||
|
|
||||||
|
w.int4 = 0;
|
||||||
|
vMachine->Push(w);
|
||||||
|
|
||||||
|
vMachine->OpCALL(w);
|
||||||
|
vMachine->Run();
|
||||||
|
w.int4 = (argCount + 2) * sizeof(vm::word);
|
||||||
|
vMachine->OpLEAVE(w);
|
||||||
|
vMachine->OpPOP(w); //Pop pointless null
|
||||||
|
vMachine->End();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int LuaScriptInterface::elements_loadDefault(lua_State * l)
|
int LuaScriptInterface::elements_loadDefault(lua_State * l)
|
||||||
{
|
{
|
||||||
int args = lua_gettop(l);
|
int args = lua_gettop(l);
|
||||||
@@ -957,6 +995,11 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
|||||||
lua_el_func[id] = luaL_ref(l, LUA_REGISTRYINDEX);
|
lua_el_func[id] = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||||
luacon_sim->elements[id].Update = &luacon_elementReplacement;
|
luacon_sim->elements[id].Update = &luacon_elementReplacement;
|
||||||
}
|
}
|
||||||
|
else if(lua_type(l, 3) == LUA_TLIGHTUSERDATA)
|
||||||
|
{
|
||||||
|
updateVirtualMachines[id] = (vm::VirtualMachine*)lua_touserdata(l, 3);
|
||||||
|
luacon_sim->elements[id].Update = &updateVM;
|
||||||
|
}
|
||||||
else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
||||||
{
|
{
|
||||||
lua_el_func[id] = 0;
|
lua_el_func[id] = 0;
|
||||||
@@ -1061,6 +1104,41 @@ int LuaScriptInterface::elements_free(lua_State * l)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaScriptInterface::initVirtualMachineAPI()
|
||||||
|
{
|
||||||
|
//Methods
|
||||||
|
struct luaL_reg vmAPIMethods [] = {
|
||||||
|
{"loadProgram", virtualMachine_loadProgram},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
luaL_register(l, "virtualMachine", vmAPIMethods);
|
||||||
|
|
||||||
|
//elem shortcut
|
||||||
|
lua_getglobal(l, "virtualMachine");
|
||||||
|
lua_setglobal(l, "vm");
|
||||||
|
|
||||||
|
int vmAPI = lua_gettop(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaScriptInterface::virtualMachine_loadProgram(lua_State * l)
|
||||||
|
{
|
||||||
|
luaL_checktype(l, 1, LUA_TSTRING);
|
||||||
|
|
||||||
|
vm::VirtualMachine * newVM = new vm::VirtualMachine(1);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const char * tempString = lua_tostring(l, 1);
|
||||||
|
int tempStringLength = lua_strlen(l, 1);
|
||||||
|
std::vector<char> programData(tempString, tempString+tempStringLength);
|
||||||
|
newVM->LoadProgram(programData);
|
||||||
|
}
|
||||||
|
catch(std::exception & e)
|
||||||
|
{
|
||||||
|
return luaL_error(l, "Unable to load program");
|
||||||
|
}
|
||||||
|
lua_pushlightuserdata(l, newVM);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool LuaScriptInterface::OnBrushChanged(int brushType, int rx, int ry)
|
bool LuaScriptInterface::OnBrushChanged(int brushType, int rx, int ry)
|
||||||
{
|
{
|
||||||
|
@@ -23,6 +23,12 @@ namespace ui
|
|||||||
class Window;
|
class Window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace vm
|
||||||
|
{
|
||||||
|
class VirtualMachine;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Because lua only has bindings for C, we're going to have to go outside "outside" the LuaScriptInterface, this means we can only have one instance :(
|
//Because lua only has bindings for C, we're going to have to go outside "outside" the LuaScriptInterface, this means we can only have one instance :(
|
||||||
|
|
||||||
#define LOCAL_LUA_DIR "Lua"
|
#define LOCAL_LUA_DIR "Lua"
|
||||||
@@ -59,6 +65,9 @@ class LuaScriptInterface: public CommandInterface {
|
|||||||
static int renderer_colourMode(lua_State * l);
|
static int renderer_colourMode(lua_State * l);
|
||||||
|
|
||||||
//Elements
|
//Elements
|
||||||
|
static vm::VirtualMachine * updateVirtualMachines[PT_NUM];
|
||||||
|
static int updateVM(UPDATE_FUNC_ARGS);
|
||||||
|
//
|
||||||
void initElementsAPI();
|
void initElementsAPI();
|
||||||
static int elements_allocate(lua_State * l);
|
static int elements_allocate(lua_State * l);
|
||||||
static int elements_element(lua_State * l);
|
static int elements_element(lua_State * l);
|
||||||
@@ -71,6 +80,10 @@ class LuaScriptInterface: public CommandInterface {
|
|||||||
static int interface_showWindow(lua_State * l);
|
static int interface_showWindow(lua_State * l);
|
||||||
static int interface_closeWindow(lua_State * l);
|
static int interface_closeWindow(lua_State * l);
|
||||||
static int interface_addComponent(lua_State * l);
|
static int interface_addComponent(lua_State * l);
|
||||||
|
|
||||||
|
//VM
|
||||||
|
void initVirtualMachineAPI();
|
||||||
|
static int virtualMachine_loadProgram(lua_State * l);
|
||||||
public:
|
public:
|
||||||
ui::Window * Window;
|
ui::Window * Window;
|
||||||
lua_State *l;
|
lua_State *l;
|
||||||
|
@@ -191,6 +191,21 @@ void Textbox::pasteIntoSelection()
|
|||||||
backingText.erase(backingText.begin()+getLowerSelectionBound(), backingText.begin()+getHigherSelectionBound());
|
backingText.erase(backingText.begin()+getLowerSelectionBound(), backingText.begin()+getHigherSelectionBound());
|
||||||
cursor = getLowerSelectionBound();
|
cursor = getLowerSelectionBound();
|
||||||
}
|
}
|
||||||
|
for(std::string::iterator iter = newText.begin(), end = newText.end(); iter != end; ++iter)
|
||||||
|
{
|
||||||
|
if(!CharacterValid(*iter))
|
||||||
|
{
|
||||||
|
if(inputType == All)
|
||||||
|
{
|
||||||
|
if(*iter == '\n' || *iter == '\r')
|
||||||
|
*iter = ' ';
|
||||||
|
else
|
||||||
|
*iter = '?';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*iter = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
backingText.insert(cursor, newText);
|
backingText.insert(cursor, newText);
|
||||||
cursor = cursor+newText.length();
|
cursor = cursor+newText.length();
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
|
@@ -86,4 +86,15 @@ namespace vm
|
|||||||
}
|
}
|
||||||
~OutOfMemoryException() throw() {};
|
~OutOfMemoryException() throw() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InvalidProgramException: public RuntimeException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InvalidProgramException() {}
|
||||||
|
const char * what() const throw()
|
||||||
|
{
|
||||||
|
return "Could not load program";
|
||||||
|
}
|
||||||
|
~InvalidProgramException() throw() {};
|
||||||
|
};
|
||||||
}
|
}
|
@@ -61,9 +61,9 @@ namespace vm
|
|||||||
|
|
||||||
TRAPDEF(partCreate)
|
TRAPDEF(partCreate)
|
||||||
{
|
{
|
||||||
//Push<int4_t>(sim->create_part(ARG(0).int4, ARG(1).int4, ARG(2).int4, ARG(3).int4));
|
printf("%d, %d, %d, %d\n", ARG(0).int4, ARG(1).int4, ARG(2).int4, ARG(3).int4);
|
||||||
printf("create_part(%d, %d, %d, %d)\n", ARG(0).int4, ARG(1).int4, ARG(2).int4, ARG(3).int4);
|
|
||||||
Push<int4_t>(0);
|
Push<int4_t>(0);
|
||||||
|
//Push<int4_t>(sim->create_part(ARG(0).int4, ARG(1).int4, ARG(2).int4, ARG(3).int4));
|
||||||
}
|
}
|
||||||
|
|
||||||
TRAPDEF(partChangeType)
|
TRAPDEF(partChangeType)
|
||||||
|
@@ -74,86 +74,87 @@ namespace vm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read one octet from file. */
|
/* Read one octet from file. */
|
||||||
int VirtualMachine::readByte(FILE *qvmfile)
|
int VirtualMachine::readByte(std::istream & input)
|
||||||
{
|
{
|
||||||
int o;
|
int o;
|
||||||
o = fgetc(qvmfile);
|
o = input.get();
|
||||||
if (o < 0) o = 0; /* EOF (hack) */
|
if (o < 0) o = 0; /* EOF (hack) */
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read little-endian 32-bit integer from file. */
|
/* Read little-endian 32-bit integer from file. */
|
||||||
int VirtualMachine::readInt(FILE *qvmfile)
|
int VirtualMachine::readInt(std::istream & input)
|
||||||
{
|
{
|
||||||
int a, b, c, d, n;
|
int a, b, c, d, n;
|
||||||
|
|
||||||
a = readByte(qvmfile);
|
a = readByte(input);
|
||||||
b = readByte(qvmfile);
|
b = readByte(input);
|
||||||
c = readByte(qvmfile);
|
c = readByte(input);
|
||||||
d = readByte(qvmfile);
|
d = readByte(input);
|
||||||
n = (a) | (b << 8) | (c << 16) | (d << 24);
|
n = (a) | (b << 8) | (c << 16) | (d << 24);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VirtualMachine::LoadProgram(char * filename)
|
int VirtualMachine::readProgram(std::istream & input)
|
||||||
{
|
{
|
||||||
FILE * qvmfile = fopen(filename, "rb");
|
|
||||||
qvm_header_t qvminfo;
|
qvm_header_t qvminfo;
|
||||||
int i, n;
|
int i, n;
|
||||||
uint1_t x[4];
|
uint1_t x[4];
|
||||||
word w;
|
word w;
|
||||||
|
|
||||||
DEBUGTRACE("Loading file...\n");
|
DEBUGTRACE("Loading file...\n");
|
||||||
qvminfo.magic = readInt(qvmfile); /* magic. */
|
qvminfo.magic = readInt(input); /* magic. */
|
||||||
if (qvminfo.magic != QVM_MAGIC)
|
if (qvminfo.magic != QVM_MAGIC)
|
||||||
{
|
{
|
||||||
DEBUGTRACE("Invalid magic");
|
DEBUGTRACE("Invalid magic");
|
||||||
//q3vm_error("Does not appear to be a QVM file.");
|
throw InvalidProgramException();
|
||||||
/* XXX: option to force continue. */
|
//q3vm_error("Does not appear to be a QVM file.");
|
||||||
return 0;
|
/* XXX: option to force continue. */
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
DEBUGTRACE("Magic OK\n");
|
DEBUGTRACE("Magic OK\n");
|
||||||
/* variable-length instructions mean instruction count != code length */
|
/* variable-length instructions mean instruction count != code length */
|
||||||
qvminfo.inscount = readInt(qvmfile);
|
qvminfo.inscount = readInt(input);
|
||||||
qvminfo.codeoff = readInt(qvmfile);
|
qvminfo.codeoff = readInt(input);
|
||||||
qvminfo.codelen = readInt(qvmfile);
|
qvminfo.codelen = readInt(input);
|
||||||
qvminfo.dataoff = readInt(qvmfile);
|
qvminfo.dataoff = readInt(input);
|
||||||
qvminfo.datalen = readInt(qvmfile);
|
qvminfo.datalen = readInt(input);
|
||||||
qvminfo.litlen = readInt(qvmfile);
|
qvminfo.litlen = readInt(input);
|
||||||
qvminfo.bsslen = readInt(qvmfile);
|
qvminfo.bsslen = readInt(input);
|
||||||
|
|
||||||
/* Code segment should follow... */
|
/* Code segment should follow... */
|
||||||
/* XXX: use fseek with SEEK_CUR? */
|
/* XXX: use fseek with SEEK_CUR? */
|
||||||
DEBUGTRACE("Searching for .code @ %d from %d\n", qvminfo.codeoff, ftell(qvmfile));
|
DEBUGTRACE("Searching for .code @ %d from %d\n", qvminfo.codeoff, input.tellg());
|
||||||
|
|
||||||
// rom = (q3vm_rom_t*)(hunk); /* ROM-in-hunk */
|
// rom = (q3vm_rom_t*)(hunk); /* ROM-in-hunk */
|
||||||
rom = (Instruction*)calloc(qvminfo.inscount, sizeof(rom[0]));
|
rom = (Instruction*)calloc(qvminfo.inscount, sizeof(rom[0]));
|
||||||
while (ftell(qvmfile) < qvminfo.codeoff)
|
while (input.tellg() < qvminfo.codeoff)
|
||||||
readByte(qvmfile);
|
readByte(input);
|
||||||
while (romSize < qvminfo.inscount)
|
while (romSize < qvminfo.inscount)
|
||||||
{
|
{
|
||||||
n = readByte(qvmfile);
|
n = readByte(input);
|
||||||
w.int4 = 0;
|
w.int4 = 0;
|
||||||
if ((i = opcodeParameterSize(n)))
|
if ((i = opcodeParameterSize(n)))
|
||||||
{
|
{
|
||||||
x[0] = x[1] = x[2] = x[3] = 0;
|
x[0] = x[1] = x[2] = x[3] = 0;
|
||||||
fread(&x, 1, i, qvmfile);
|
input.readsome((char*)x, 4);
|
||||||
w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
|
w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
|
||||||
}
|
}
|
||||||
rom[romSize].Operation = n;
|
rom[romSize].Operation = n;
|
||||||
rom[romSize].Parameter = w;
|
rom[romSize].Parameter = w;
|
||||||
romSize++;
|
romSize++;
|
||||||
}
|
}
|
||||||
DEBUGTRACE("After loading code: at %d, should be %d\n", ftell(qvmfile), qvminfo.codeoff + qvminfo.codelen);
|
DEBUGTRACE("After loading code: at %d, should be %d\n", input.tellg(), qvminfo.codeoff + qvminfo.codelen);
|
||||||
|
|
||||||
/* Then data segment. */
|
/* Then data segment. */
|
||||||
// ram = hunk + ((romlen + 3) & ~3); /* RAM-in-hunk */
|
// ram = hunk + ((romlen + 3) & ~3); /* RAM-in-hunk */
|
||||||
ram = hunk;
|
ram = hunk;
|
||||||
DEBUGTRACE("Searching for .data @ %d from %d\n", qvminfo.dataoff, ftell(qvmfile));
|
DEBUGTRACE("Searching for .data @ %d from %d\n", qvminfo.dataoff, input.tellg());
|
||||||
while (ftell(qvmfile) < qvminfo.dataoff)
|
while (input.tellg() < qvminfo.dataoff)
|
||||||
readByte(qvmfile);
|
readByte(input);
|
||||||
for (n = 0; n < (qvminfo.datalen / sizeof(uint1_t)); n++)
|
for (n = 0; n < (qvminfo.datalen / sizeof(uint1_t)); n++)
|
||||||
{
|
{
|
||||||
i = fread(&x, 1, sizeof(x), qvmfile);
|
i = input.readsome((char*)x, sizeof(x));
|
||||||
w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
|
w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
|
||||||
*((word*)(ram + ramSize)) = w;
|
*((word*)(ram + ramSize)) = w;
|
||||||
ramSize += sizeof(word);
|
ramSize += sizeof(word);
|
||||||
@@ -164,7 +165,7 @@ namespace vm
|
|||||||
DEBUGTRACE("Loading .lit\n");
|
DEBUGTRACE("Loading .lit\n");
|
||||||
for (n = 0; n < (qvminfo.litlen / sizeof(uint1_t)); n++)
|
for (n = 0; n < (qvminfo.litlen / sizeof(uint1_t)); n++)
|
||||||
{
|
{
|
||||||
i = fread(&x, 1, sizeof(x), qvmfile);
|
i = input.readsome((char*)x, sizeof(x));
|
||||||
memcpy(&(w.uint1), &x, sizeof(x)); /* no byte-swapping. */
|
memcpy(&(w.uint1), &x, sizeof(x)); /* no byte-swapping. */
|
||||||
*((word*)(ram + ramSize)) = w;
|
*((word*)(ram + ramSize)) = w;
|
||||||
ramSize += sizeof(word);
|
ramSize += sizeof(word);
|
||||||
@@ -187,8 +188,8 @@ namespace vm
|
|||||||
{
|
{
|
||||||
int stacksize = 0x10000;
|
int stacksize = 0x10000;
|
||||||
dataStack = ramSize - (stacksize / 2);
|
dataStack = ramSize - (stacksize / 2);
|
||||||
//returnStack = ramSize;
|
returnStack = ramSize;
|
||||||
returnStack = dataStack+4;
|
//returnStack = dataStack+4;
|
||||||
RP = returnStack;
|
RP = returnStack;
|
||||||
DP = dataStack;
|
DP = dataStack;
|
||||||
}
|
}
|
||||||
@@ -201,6 +202,122 @@ namespace vm
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VirtualMachine::LoadProgram(std::vector<char> data)
|
||||||
|
{
|
||||||
|
/*class vectorwrapbuf : public std::basic_streambuf<char, std::char_traits<char> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
vectorwrapbuf(std::vector<char> &vec) {
|
||||||
|
setg(vec.data(), vec.data(), vec.data() + vec.size());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
vectorwrapbuf databuf(data);
|
||||||
|
std::istream is(&databuf);
|
||||||
|
return readProgram(is);*/
|
||||||
|
std::stringstream ss(std::string(data.begin(), data.end()));
|
||||||
|
return readProgram((std::istream &)ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
int VirtualMachine::LoadProgram(char * filename)
|
||||||
|
{
|
||||||
|
/*FILE * qvmfile = fopen(filename, "rb");
|
||||||
|
qvm_header_t qvminfo;
|
||||||
|
int i, n;
|
||||||
|
uint1_t x[4];
|
||||||
|
word w;
|
||||||
|
|
||||||
|
DEBUGTRACE("Loading file...\n");
|
||||||
|
qvminfo.magic = readInt(qvmfile);
|
||||||
|
if (qvminfo.magic != QVM_MAGIC)
|
||||||
|
{
|
||||||
|
DEBUGTRACE("Invalid magic");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DEBUGTRACE("Magic OK\n");
|
||||||
|
|
||||||
|
qvminfo.inscount = readInt(qvmfile);
|
||||||
|
qvminfo.codeoff = readInt(qvmfile);
|
||||||
|
qvminfo.codelen = readInt(qvmfile);
|
||||||
|
qvminfo.dataoff = readInt(qvmfile);
|
||||||
|
qvminfo.datalen = readInt(qvmfile);
|
||||||
|
qvminfo.litlen = readInt(qvmfile);
|
||||||
|
qvminfo.bsslen = readInt(qvmfile);
|
||||||
|
|
||||||
|
|
||||||
|
DEBUGTRACE("Searching for .code @ %d from %d\n", qvminfo.codeoff, ftell(qvmfile));
|
||||||
|
|
||||||
|
rom = (Instruction*)calloc(qvminfo.inscount, sizeof(rom[0]));
|
||||||
|
while (ftell(qvmfile) < qvminfo.codeoff)
|
||||||
|
readByte(qvmfile);
|
||||||
|
while (romSize < qvminfo.inscount)
|
||||||
|
{
|
||||||
|
n = readByte(qvmfile);
|
||||||
|
w.int4 = 0;
|
||||||
|
if ((i = opcodeParameterSize(n)))
|
||||||
|
{
|
||||||
|
x[0] = x[1] = x[2] = x[3] = 0;
|
||||||
|
fread(&x, 1, i, qvmfile);
|
||||||
|
w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
|
||||||
|
}
|
||||||
|
rom[romSize].Operation = n;
|
||||||
|
rom[romSize].Parameter = w;
|
||||||
|
romSize++;
|
||||||
|
}
|
||||||
|
DEBUGTRACE("After loading code: at %d, should be %d\n", ftell(qvmfile), qvminfo.codeoff + qvminfo.codelen);
|
||||||
|
|
||||||
|
|
||||||
|
ram = hunk;
|
||||||
|
DEBUGTRACE("Searching for .data @ %d from %d\n", qvminfo.dataoff, ftell(qvmfile));
|
||||||
|
while (ftell(qvmfile) < qvminfo.dataoff)
|
||||||
|
readByte(qvmfile);
|
||||||
|
for (n = 0; n < (qvminfo.datalen / sizeof(uint1_t)); n++)
|
||||||
|
{
|
||||||
|
i = fread(&x, 1, sizeof(x), qvmfile);
|
||||||
|
w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
|
||||||
|
*((word*)(ram + ramSize)) = w;
|
||||||
|
ramSize += sizeof(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEBUGTRACE("Loading .lit\n");
|
||||||
|
for (n = 0; n < (qvminfo.litlen / sizeof(uint1_t)); n++)
|
||||||
|
{
|
||||||
|
i = fread(&x, 1, sizeof(x), qvmfile);
|
||||||
|
memcpy(&(w.uint1), &x, sizeof(x));
|
||||||
|
*((word*)(ram + ramSize)) = w;
|
||||||
|
ramSize += sizeof(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGTRACE("Allocating .bss %d (%X) bytes\n", qvminfo.bsslen, qvminfo.bsslen);
|
||||||
|
ramSize += qvminfo.bsslen;
|
||||||
|
|
||||||
|
hunkFree = hunkSize - ((ramSize * sizeof(uint1_t)) + 4);
|
||||||
|
|
||||||
|
DEBUGTRACE("VM hunk has %d of %d bytes free (RAM = %d B).\n", hunkFree, hunkSize, ramSize);
|
||||||
|
if (ramSize > hunkSize)
|
||||||
|
{
|
||||||
|
throw OutOfMemoryException();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
int stacksize = 0x10000;
|
||||||
|
dataStack = ramSize - (stacksize / 2);
|
||||||
|
//returnStack = ramSize;
|
||||||
|
returnStack = dataStack+4;
|
||||||
|
RP = returnStack;
|
||||||
|
DP = dataStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PC = romSize + 1;
|
||||||
|
|
||||||
|
ramMask = ramSize;
|
||||||
|
|
||||||
|
return 1;*/
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualMachine::End()
|
void VirtualMachine::End()
|
||||||
{
|
{
|
||||||
PC = romSize+1;
|
PC = romSize+1;
|
||||||
|
@@ -117,8 +117,9 @@ namespace vm
|
|||||||
};
|
};
|
||||||
#undef OPDEF
|
#undef OPDEF
|
||||||
|
|
||||||
int readByte(FILE *qvmfile);
|
int readProgram(std::istream & input);
|
||||||
int readInt(FILE *qvmfile);
|
int readByte(std::istream & input);
|
||||||
|
int readInt(std::istream & input);
|
||||||
int opcodeParameterSize(int opcode);
|
int opcodeParameterSize(int opcode);
|
||||||
int syscall(int programCounter);
|
int syscall(int programCounter);
|
||||||
|
|
||||||
@@ -153,6 +154,7 @@ public:
|
|||||||
virtual ~VirtualMachine();
|
virtual ~VirtualMachine();
|
||||||
|
|
||||||
int LoadProgram(char * filename);
|
int LoadProgram(char * filename);
|
||||||
|
int LoadProgram(std::vector<char> fileData);
|
||||||
int Run();
|
int Run();
|
||||||
int CallInterpreted(int address);
|
int CallInterpreted(int address);
|
||||||
void End();
|
void End();
|
||||||
|
Reference in New Issue
Block a user