summaryrefslogtreecommitdiff
path: root/src/pim/Machine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pim/Machine.cpp')
-rw-r--r--src/pim/Machine.cpp637
1 files changed, 0 insertions, 637 deletions
diff --git a/src/pim/Machine.cpp b/src/pim/Machine.cpp
deleted file mode 100644
index a954d31..0000000
--- a/src/pim/Machine.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
-//Virtual machine
-
-#include <iostream>
-#include "Machine.h"
-#include "Opcodes.h"
-#include "simulation/Simulation.h"
-namespace pim
-{
- /*unsigned char * rom;
- int romSize;
- int romMask;
-
- unsigned char * ram;
- int ramSize;
- int ramMask;
-
- int programStack;
- int callStack;*/
-
- VirtualMachine::VirtualMachine(Simulation * simulation) :
- rom(NULL),
- ram(NULL),
- sim(simulation)
- {
-
- }
-
- void VirtualMachine::LoadProgram(std::vector<unsigned char> fileData)
- {
- int lastBit = 0;
-
- if(!(fileData[0] == 'P' && fileData[1] == 'V' && fileData[2] == 'M' && fileData[3] == '1' && fileData.size() >= 16))
- {
- throw InvalidProgramException();
- }
-
- int macroSize = 0, propSize = 0, codeSize = 0;
- macroSize = fileData[4];
- macroSize |= fileData[5] << 8;
- macroSize |= fileData[6] << 16;
- macroSize |= fileData[7] << 24;
-
- propSize = fileData[8];
- propSize |= fileData[9] << 8;
- propSize |= fileData[10] << 16;
- propSize |= fileData[11] << 24;
-
- codeSize = fileData[12];
- codeSize |= fileData[13] << 8;
- codeSize |= fileData[14] << 16;
- codeSize |= fileData[15] << 24;
-
- if(fileData.size() < 16 + macroSize + propSize + codeSize)
- {
- throw InvalidProgramException();
- }
-
- //std::vector<std::pair<int, int> > insertions;
-
- int macroOffset = 16;
- int propOffset = macroOffset+macroSize;
- int codeOffset = propOffset+propSize;
-
-
- int filePosition = macroOffset;
- while(filePosition + 4 < macroSize + macroOffset)
- {
- std::string macro;
- int macroPosition;
- int macroValue;
-
- macroPosition = fileData[filePosition++];
- macroPosition |= fileData[filePosition++] << 8;
- macroPosition |= fileData[filePosition++] << 16;
- macroPosition |= fileData[filePosition++] << 24;
-
- int stringLength = fileData[filePosition++];
- if(filePosition + stringLength > macroSize + macroOffset)
- {
- throw InvalidProgramException();
- }
-
- macro.insert(macro.begin(), fileData.begin()+filePosition, fileData.begin()+filePosition+stringLength);
- filePosition += stringLength;
-
- bool resolved = false;
- for(int i = 0; i < PT_NUM; i++)
- {
- if(sim->elements[i].Enabled && sim->elements[i].Identifier == macro)
- {
- macroValue = i;
- resolved = true;
- }
- }
- if(!resolved)
- {
- throw UnresolvedValueException(macro);
- }
-
- if(macroPosition + 3 >= codeSize)
- {
- throw InvalidProgramException();
- }
-
- std::cout << "Macro insertion [" << macro << "] at " << macroPosition << " with " << macroValue << std::endl;
-
- fileData[codeOffset+macroPosition] = macroValue & 0xFF;
- fileData[codeOffset+macroPosition+1] = (macroValue >> 8) & 0xFF;
- fileData[codeOffset+macroPosition+2] = (macroValue >> 16) & 0xFF;
- fileData[codeOffset+macroPosition+3] = (macroValue >> 24) & 0xFF;
- //insertions.push_back(std::pair<int, int>(macroPosition, macroValue));
- }
-
- filePosition = propOffset;
- while(filePosition + 4 < propSize + propOffset)
- {
- std::string prop;
- int propPosition;
- int propValue;
-
- propPosition = fileData[filePosition++];
- propPosition |= fileData[filePosition++] << 8;
- propPosition |= fileData[filePosition++] << 16;
- propPosition |= fileData[filePosition++] << 24;
-
- int stringLength = fileData[filePosition++];
- if(filePosition + stringLength > propSize + propOffset)
- {
- throw InvalidProgramException();
- }
-
- prop.insert(prop.begin(), fileData.begin()+filePosition, fileData.begin()+filePosition+stringLength);
- filePosition += stringLength;
-
- bool resolved = false;
-
- std::vector<StructProperty> properties = Particle::GetProperties();
- for(std::vector<StructProperty>::iterator iter = properties.begin(), end = properties.end(); iter != end; ++iter)
- {
- StructProperty property = *iter;
- std::cout << property.Offset << std::endl;
- if(property.Name == prop &&
- (property.Type == StructProperty::ParticleType ||
- property.Type == StructProperty::Colour ||
- property.Type == StructProperty::Integer ||
- property.Type == StructProperty::UInteger ||
- property.Type == StructProperty::Float)
- )
- {
- propValue = property.Offset;
- resolved = true;
- break;
- }
- }
- if(!resolved)
- {
- throw UnresolvedValueException(prop);
- }
-
- if(propPosition + 3 >= codeSize)
- {
- throw InvalidProgramException();
- }
-
- std::cout << "Property insertion [" << prop << "] at " << propPosition << " with " << propValue << std::endl;
-
- fileData[codeOffset+propPosition] = propValue & 0xFF;
- fileData[codeOffset+propPosition+1] = (propValue >> 8) & 0xFF;
- fileData[codeOffset+propPosition+2] = (propValue >> 16) & 0xFF;
- fileData[codeOffset+propPosition+3] = (propValue >> 24) & 0xFF;
- //insertions.push_back(std::pair<int, int>(macroPosition, macroValue));
- }
-
- std::vector<unsigned char> programData;
- programData.insert(programData.begin(), fileData.begin()+codeOffset, fileData.begin()+codeOffset+codeSize);
-
- romSize = programData.size();
-
- for (lastBit = 0; romSize > (1 << lastBit); lastBit++ ) { }
- romSize = 1 << lastBit;
- romMask = romSize - 1;
-
- rom = new Instruction[romSize];
-
- int pc = 0;
- int programPosition = 0;
-
- while(programPosition < programData.size())
- {
- int argSize = 0;
- Instruction instruction;
- instruction.Opcode = programData[programPosition++];
- if(argSize = OpcodeArgSize(instruction.Opcode))
- {
- if(argSize == 4 && programPosition+3 < programData.size())
- {
- int tempInt = 0;
- tempInt |= programData[programPosition];
- tempInt |= programData[programPosition+1] << 8;
- tempInt |= programData[programPosition+2] << 16;
- tempInt |= programData[programPosition+3] << 24;
-
-
- std::cout << "Got integer " << tempInt << std::endl;
-
- if(instruction.Opcode == Opcode::LoadProperty || instruction.Opcode == Opcode::StoreProperty)
- {
- if(tempInt > offsetof(Particle, dcolour))
- throw InvalidProgramException();
- }
-
- instruction.Parameter.Integer = tempInt;
-
- programPosition += 4;
- }
- }
- else
- {
- instruction.Parameter.Integer = 0;
- }
- rom[pc++] = instruction;
- }
- romSize = pc;
-
- ramSize = 1024;
- ramMask = ramSize - 1;
-
- ram = new unsigned char[ramSize];
- programStack = ramSize-1;
- callStack = ramSize-260;
-
- framePointer = callStack;
- callStack += WORDSIZE; //Since there's nothing on the stack, it shouldn't point to the item on the bottom
- }
-
- int VirtualMachine::OpcodeArgSize(int opcode)
- {
- switch(opcode)
- {
- case Opcode::Load:
- case Opcode::Store:
- case Opcode::Constant:
- case Opcode::Increment:
- case Opcode::JumpEqual:
- case Opcode::JumpNotEqual:
- case Opcode::JumpGreater:
- case Opcode::JumpGreaterEqual:
- case Opcode::JumpLess:
- case Opcode::JumpLessEqual:
- case Opcode::Jump:
- case Opcode::Return:
- case Opcode::LocalEnter:
- case Opcode::LoadProperty:
- case Opcode::StoreProperty:
- return 4;
- case Opcode::Discard:
- case Opcode::Duplicate:
- case Opcode::Add:
- case Opcode::Subtract:
- case Opcode::Multiply:
- case Opcode::Divide:
- case Opcode::Modulus:
- case Opcode::Negate:
- case Opcode::Create:
- case Opcode::Transform:
- case Opcode::Get:
- case Opcode::Position:
- case Opcode::Kill:
- return 0;
- }
- }
-
- void VirtualMachine::Run()
- {
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- //std::string names[] = { "Load", "Store", "Constant", "Increment", "Discard", "Duplicate", "Add", "Subtract", "Multiply", "Divide", "Modulus", "Negate", "Create", "Transform", "Get", "Position", "Kill", "JumpEqual", "JumpNotEqual", "JumpGreater", "JumpGreaterEqual", "JumpLess", "JumpLessEqual", "Jump", "Return", "LocalEnter"};
-
- Word temp1;
- Word temp2;
- Word temp3;
- Word temp4;
- int temp;
- while(programCounter < romSize)
- {
- Word argument = rom[programCounter].Parameter;
- //std::cerr << programCounter << "\t" << names[rom[programCounter].Opcode] << "\t" << argument.Integer << std::endl;//"\t";
- switch(rom[programCounter].Opcode)
- {
- case Opcode::Load:
- PSPush(CSA(argument.Integer));
- break;
- case Opcode::Store:
- CSA(argument.Integer) = PSPop();
- break;
- case Opcode::Constant:
- PSPush(argument);
- break;
- case Opcode::Increment:
- PS().Integer += argument.Integer;
- break;
- case Opcode::Discard:
- programStack += WORDSIZE;
- break;
- case Opcode::Duplicate:
- PSPush(PS());
- break;
- case Opcode::Add:
- PSPush(PSPop().Integer + PSPop().Integer);
- break;
- case Opcode::Subtract:
- temp1 = PSPop();
- PSPush(PSPop().Integer - temp1.Integer);
- break;
- case Opcode::Multiply:
- PSPush(PSPop().Integer * PSPop().Integer);
- break;
- case Opcode::Divide:
- temp1 = PSPop();
- PSPush(PSPop().Integer / temp1.Integer);
- break;
- case Opcode::Modulus:
- temp1 = PSPop();
- PSPush(PSPop().Integer % temp1.Integer);
- break;
- case Opcode::Negate:
- PS().Integer = -PS().Integer;
- break;
- case Opcode::Create:
- temp1 = PSPop();
- temp2 = PSPop();
- temp3 = PSPop();
- PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer));
- break;
- case Opcode::Transform:
- PSPop();
- PSPop();
- PSPush((Word)-1);
- break;
- case Opcode::Get:
- temp1 = PSPop();
- temp2 = PSPop();
- if(temp1.Integer < 0 || temp1.Integer >= YRES || temp2.Integer < 0 || temp2.Integer >= XRES || !(temp = sim->pmap[temp1.Integer][temp2.Integer]))
- {
- PSPush(-1);
- break;
- }
- PSPush(temp>>8);
- break;
- case Opcode::Position:
- temp1 = PSPop();
- if(temp1.Integer < 0 || temp1.Integer >= NPART || !sim->parts[temp1.Integer].type)
- {
- PSPush(-1);
- PSPush(-1);
- break;
- }
- PSPush((int)sim->parts[temp1.Integer].x);
- PSPush((int)sim->parts[temp1.Integer].y);
- break;
- case Opcode::Kill:
- sim->kill_part(PSPop().Integer);
- PSPush((Word)0);
- break;
- case Opcode::LoadProperty:
- PSPush(PPROP(PSPop().Integer, argument.Integer));
- break;
- case Opcode::StoreProperty:
- temp1 = PSPop();
- PPROP(temp1.Integer, argument.Integer) = PSPop();
- break;
- case Opcode::JumpEqual:
- if(PSPop().Integer == PSPop().Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpNotEqual:
- if(PSPop().Integer != PSPop().Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpGreater:
- temp1 = PSPop();
- if(PSPop().Integer > temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpGreaterEqual:
- temp1 = PSPop();
- if(PSPop().Integer >= temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpLess:
- temp1 = PSPop();
- if(PSPop().Integer < temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpLessEqual:
- temp1 = PSPop();
- if(PSPop().Integer <= temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::Jump:
- programCounter = argument.Integer-1;
- break;
- case Opcode::Return:
- callStack += argument.Integer;
- break;
- case Opcode::LocalEnter:
- callStack -= argument.Integer;
- break;
- }
- //std::cout << programStack << std::endl;
- programCounter++;
- }
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- }
-
- void VirtualMachine::Compile()
- {
- while(programCounter < romSize)
- {
- Word argument = rom[programCounter].Parameter;
- switch(rom[programCounter].Opcode)
- {
- case Opcode::Load:
- emit("83 EF 04"); //sub edi 4
-
- //Load value at base stack + offset into eax
- emit("8B 85"); //mov eax [ebp+ram+offset]
- emit((intptr_t) (ram - argument.Integer));
-
- //Store value in eax onto top of program stack
- emit("89 07"); //mov [edi], eax
- emit((intptr_t) (ram));
- break;
- case Opcode::Store:
- //Load value on top of the program stack into eax
- emit("8B 07"); //mov eax [edi]
- emit((intptr_t) (ram));
-
- //Load value in eax onto top of program stack
- emit("89 85"); //mov [ebp+ram+offset], eax
- emit((intptr_t) (ram - argument.Integer));
-
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Constant:
- emit("83 EF 04"); //sub edi 4
-
- emit("C7 07"); //mov [edi] constant
- emit((int) (argument.Integer));
- break;
- case Opcode::Increment:
- emit("81 07"); //add [edi] constant
- emit((int) (argument.Integer));
- break;
- case Opcode::Discard:
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Duplicate:
- //Copy value on stack into register
- emit("8B 07"); //mov eax [edi]
- //Adjust program stack pointer
- emit("83 EF 04"); //sub edi 4
- //Move value in eax into program stack
- emit("89 07"); //mov [edi], eax
- break;
- case Opcode::Add:
- emit("8B 07"); //mov eax [edi]
- emit("01 47 04"); //add [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Subtract:
- emit("8B 07"); //mov eax [edi]
- emit("29 47 04"); //sub [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Multiply:
- emit("8B 47 04"); //mov eax [edi+4]
- emit("F7 2F"); //imul [edi]
- emit("89 47 04"); //mov [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Divide:
- emit("8B 47 04");//mov eax [edi+4]
- emit("99"); //cdq
- emit("F7 3F"); //idiv [edi]
- emit("89 47 04"); //mov [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Modulus:
- emit("8B 47 04"); // mov eax [edi+4]
- emit("99"); // cdq
- emit("F7 3F"); // idiv [edi]
- emit("89 57 04"); // mov [edi+4] edx
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Negate:
- emit("F7 1F"); //neg [edi]
- break;
- case Opcode::Create:
- //temp1 = PSPop();
- //temp2 = PSPop();
- //temp3 = PSPop();
- //PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer));
- break;
- case Opcode::Transform:
- //PSPop();
- //PSPop();
- //PSPush((Word)-1);
- break;
- case Opcode::Get:
- //temp1 = PSPop();
- //temp2 = PSPop();
- //if(temp1.Integer < 0 || temp1.Integer >= YRES || temp2.Integer < 0 || temp2.Integer >= XRES || !(temp = sim->pmap[temp1.Integer][temp2.Integer]))
- //{
- // PSPush(-1);
- // break;
- //}
- //PSPush(temp>>8);
- break;
- case Opcode::Position:
- //temp1 = PSPop();
- //if(temp1.Integer < 0 || temp1.Integer >= NPART || !sim->parts[temp1.Integer].type)
- //{
- // PSPush(-1);
- // PSPush(-1);
- // break;
- //}
- //PSPush((int)sim->parts[temp1.Integer].x);
- //PSPush((int)sim->parts[temp1.Integer].y);
- break;
- case Opcode::Kill:
- //sim->kill_part(PSPop().Integer);
- //PSPush((Word)0);
- break;
- case Opcode::LoadProperty:
- //PSPush(PPROP(PSPop().Integer, argument.Integer));
- break;
- case Opcode::StoreProperty:
- //temp1 = PSPop();
- //PPROP(temp1.Integer, argument.Integer) = PSPop();
- break;
- case Opcode::JumpEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("75 06"); //jne +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpNotEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("74 06"); //je +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpGreater:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7E 06"); //jng +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpGreaterEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7C 06"); //jnge +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpLess:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7D 06"); //jnl +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpLessEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7F 06"); //jnle +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::Jump:
- //programCounter = argument.Integer-1;
- break;
- case Opcode::Return:
- emit("81 C6"); //add esi constant
- emit(argument.Integer);
- break;
- case Opcode::LocalEnter:
- emit("81 EE"); //sub esi constant
- emit(argument.Integer);
- break;
- }
- //std::cout << programStack << std::endl;
- programCounter++;
- }
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- }
-
- void VirtualMachine::emit(std::string opcode)
- {
-
- }
-
- void VirtualMachine::emit(int constant)
- {
-
- }
-
- void VirtualMachine::CallCompiled(std::string entryPoint)
- {
-
- }
-
- void VirtualMachine::CallCompiled(int entryPoint)
- {
-
- }
-
- void VirtualMachine::Call(std::string entryPoint)
- {
-
- }
-
- void VirtualMachine::Call(int entryPoint)
- {
- programCounter = entryPoint;
- Run();
- }
-}