Adds windows build script, adds section start to explink, improves decompilation with expdump.
This commit is contained in:
parent
47b608f2c8
commit
5d1d274afd
11 changed files with 540 additions and 423 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -210,3 +210,9 @@ FakesAssemblies/
|
|||
GeneratedArtifacts/
|
||||
_Pvt_Extensions/
|
||||
ModelManifest.xml
|
||||
|
||||
|
||||
*.exe
|
||||
*.lib
|
||||
*.dll
|
||||
SDL-1.2.15/
|
21
libvm/build.bat
Normal file
21
libvm/build.bat
Normal file
|
@ -0,0 +1,21 @@
|
|||
@echo off
|
||||
SET PATHSAVE=%PATH%
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
|
||||
|
||||
SET INIT = /nologo
|
||||
SET OPTIONS = /Zp1
|
||||
|
||||
REM echo Building explink...
|
||||
REM cl %INIT% explink.c getopt.c %OPTIONS%
|
||||
|
||||
REM echo Building expdump...
|
||||
REM cl %INIT% expdump.c getopt.c %OPTIONS%
|
||||
|
||||
echo Building emulator...
|
||||
SET LIBS= /NXCOMPAT /DYNAMICBASE "SDL.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /OPT:REF /INCREMENTAL:NO /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 /NODEFAULTLIB:msvcrt.lib
|
||||
cl %INIT% /I "SDL-1.2.15\include" emulator.c vm.c getopt.c %OPTIONS% /link %LIBS%
|
||||
|
||||
echo Cleaning up...
|
||||
del *.obj
|
||||
SET PATH=%PATHSAVE%
|
||||
echo Done.
|
238
libvm/emulator.c
Normal file
238
libvm/emulator.c
Normal file
|
@ -0,0 +1,238 @@
|
|||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <SDL.h>
|
||||
#include <stdbool.h>
|
||||
#include "vm.h"
|
||||
#include "exp.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
bool running = true;
|
||||
|
||||
/**
|
||||
* An assertion the VM does.
|
||||
* @param assertion If zero, the assertion failed.
|
||||
* @param msg The message that should be shown when the assertion fails.
|
||||
*/
|
||||
void vm_assert(int assertion, const char *msg)
|
||||
{
|
||||
if (assertion)
|
||||
return;
|
||||
printf("Assertion failed: %s\n", msg);
|
||||
running = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hosts syscall implementation.
|
||||
* @param process The process that calls the syscall.
|
||||
* @param info Additional information for the syscall. Contains arguments and results.
|
||||
*/
|
||||
uint32_t vm_syscall(spu_t *process, cmdinput_t *info)
|
||||
{
|
||||
fprintf(stdout, "SYSCALL [%d]: (%d, %d)\n", info->info, info->input0, info->input1);
|
||||
if (info->info == 0)
|
||||
running = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hosts hardware IO implementation.
|
||||
* @param process The process that wants to do IO.
|
||||
* @param info Additional information for the HWIO. Contains arguments and results.
|
||||
*/
|
||||
uint32_t vm_hwio(spu_t *process, cmdinput_t *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
spu_t mainCore;
|
||||
|
||||
void dump_vm()
|
||||
{
|
||||
printf(
|
||||
"%8X %3d %3d %1X [",
|
||||
mainCore.codePointer,
|
||||
mainCore.stackPointer,
|
||||
mainCore.basePointer,
|
||||
mainCore.flags
|
||||
);
|
||||
|
||||
for (int i = 1; i < mainCore.stackPointer; i++)
|
||||
{
|
||||
printf(" %d", mainCore.stack[i]);
|
||||
}
|
||||
|
||||
printf(" ]\n");
|
||||
}
|
||||
|
||||
void update_vm()
|
||||
{
|
||||
vm_step_process(&mainCore);
|
||||
|
||||
// dump_vm();
|
||||
}
|
||||
|
||||
void update_input(SDL_Event *ev)
|
||||
{
|
||||
switch (ev->type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void initialize_vm()
|
||||
{
|
||||
// Initialize memory
|
||||
mainCore.memoryBase = 0x00; // Linear memory, start at 0x00
|
||||
mainCore.memorySize = 0x4000000; // 64 MB;
|
||||
mainCore.memory = malloc(mainCore.memorySize);
|
||||
|
||||
// Initialize code execution
|
||||
mainCore.code = mainCore.memory;
|
||||
mainCore.codeLength = mainCore.memorySize / sizeof(instruction_t);
|
||||
|
||||
// Setup registers
|
||||
mainCore.codePointer = 0;
|
||||
mainCore.stackPointer = 0;
|
||||
mainCore.basePointer = 0;
|
||||
mainCore.flags = 0;
|
||||
|
||||
// Clear stack
|
||||
memset(mainCore.stack, 0, VM_STACKSIZE * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
bool load_exp(const char *fileName)
|
||||
{
|
||||
FILE *f = fopen(fileName, "rb");
|
||||
if (f == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not open file %s\n", fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expfile_t fileHeader;
|
||||
|
||||
if (fread(&fileHeader, 1, sizeof(expfile_t), f) != sizeof(expfile_t))
|
||||
{
|
||||
fprintf(stderr, "File %s does not contain a valid header.\n", fileName);
|
||||
return false;
|
||||
}
|
||||
if (fileHeader.magicNumber != EXP_MAGIC)
|
||||
{
|
||||
fprintf(stderr, "Invalid magic in %s\n", fileName);
|
||||
return false;
|
||||
}
|
||||
if (fileHeader.majorVersion != 1 && fileHeader.minorVersion == 0)
|
||||
{
|
||||
fprintf(
|
||||
stderr, "Invalid version %s: %d.%d\n",
|
||||
fileName,
|
||||
fileHeader.majorVersion, fileHeader.minorVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < fileHeader.numSections; i++)
|
||||
{
|
||||
expsection_t section;
|
||||
|
||||
fseek(f, fileHeader.posSections + i * sizeof(expsection_t), SEEK_SET);
|
||||
fread(§ion, 1, sizeof(expsection_t), f);
|
||||
|
||||
fseek(f, section.start, SEEK_SET);
|
||||
|
||||
uint8_t *sectionInRam = (uint8_t*)mainCore.memory + section.base;
|
||||
int len = fread(sectionInRam, 1, section.length, f);
|
||||
if (len != section.length)
|
||||
fprintf(stderr, "Read invalid size.\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Required before ANY virtual machine memory operations...
|
||||
initialize_vm();
|
||||
|
||||
// Load the EXP file
|
||||
if (argc > 1)
|
||||
{
|
||||
if (!load_exp(argv[1])) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
return 1;
|
||||
}
|
||||
atexit(SDL_Quit);
|
||||
|
||||
SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_DOUBLEBUF);
|
||||
SDL_WM_SetCaption("DasOS Virtual Platform", NULL);
|
||||
|
||||
dump_vm();
|
||||
|
||||
SDL_Event ev;
|
||||
while (running)
|
||||
{
|
||||
while (SDL_PollEvent(&ev))
|
||||
{
|
||||
update_input(&ev);
|
||||
}
|
||||
|
||||
uint32_t start = SDL_GetTicks();
|
||||
|
||||
do {
|
||||
for (int i = 0; i < 50 && running; i++)
|
||||
{
|
||||
update_vm();
|
||||
}
|
||||
} while (running && (SDL_GetTicks() - start) <= 32);
|
||||
|
||||
{ // copy screen
|
||||
SDL_LockSurface(screen);
|
||||
memcpy(
|
||||
screen->pixels,
|
||||
(uint8_t*)mainCore.memory + 4096,
|
||||
screen->h * screen->pitch);
|
||||
SDL_UnlockSurface(screen);
|
||||
}
|
||||
|
||||
SDL_Flip(screen);
|
||||
}
|
||||
|
||||
SDL_WM_SetCaption("DasOS Virtual Platform - STOPPED", NULL);
|
||||
|
||||
running = true;
|
||||
while (running)
|
||||
{
|
||||
while (SDL_PollEvent(&ev))
|
||||
{
|
||||
if (ev.type == SDL_QUIT)
|
||||
running = false;
|
||||
else if (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE)
|
||||
running = false;
|
||||
}
|
||||
|
||||
SDL_Flip(screen);
|
||||
|
||||
SDL_Delay(32);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE * __cdecl __iob_func(void)
|
||||
{
|
||||
static FILE iob[3];
|
||||
iob[0] = *stdin;
|
||||
iob[1] = *stdout;
|
||||
iob[2] = *stderr;
|
||||
return iob;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "explink", "explink.vcxproj", "{2A84DC2E-34B9-48A5-8DE5-170C367B471E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "expdump", "expdump.vcxproj", "{C685C35A-C310-4A9D-AF6F-98CCBD388683}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2A84DC2E-34B9-48A5-8DE5-170C367B471E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2A84DC2E-34B9-48A5-8DE5-170C367B471E}.Debug|x64.Build.0 = Debug|x64
|
||||
{2A84DC2E-34B9-48A5-8DE5-170C367B471E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{2A84DC2E-34B9-48A5-8DE5-170C367B471E}.Debug|x86.Build.0 = Debug|Win32
|
||||
{2A84DC2E-34B9-48A5-8DE5-170C367B471E}.Release|x64.ActiveCfg = Release|x64
|
||||
{2A84DC2E-34B9-48A5-8DE5-170C367B471E}.Release|x64.Build.0 = Release|x64
|
||||
{2A84DC2E-34B9-48A5-8DE5-170C367B471E}.Release|x86.ActiveCfg = Release|Win32
|
||||
{2A84DC2E-34B9-48A5-8DE5-170C367B471E}.Release|x86.Build.0 = Release|Win32
|
||||
{C685C35A-C310-4A9D-AF6F-98CCBD388683}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C685C35A-C310-4A9D-AF6F-98CCBD388683}.Debug|x64.Build.0 = Debug|x64
|
||||
{C685C35A-C310-4A9D-AF6F-98CCBD388683}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C685C35A-C310-4A9D-AF6F-98CCBD388683}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C685C35A-C310-4A9D-AF6F-98CCBD388683}.Release|x64.ActiveCfg = Release|x64
|
||||
{C685C35A-C310-4A9D-AF6F-98CCBD388683}.Release|x64.Build.0 = Release|x64
|
||||
{C685C35A-C310-4A9D-AF6F-98CCBD388683}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C685C35A-C310-4A9D-AF6F-98CCBD388683}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -125,7 +125,7 @@ void disassemble(instruction_t *list, uint32_t count, uint32_t base, FILE *f)
|
|||
if (knownInstruction != NULL)
|
||||
{
|
||||
fprintf(f, "%s", knownInstruction->name);
|
||||
if (instr.input0 == VM_INPUT_ARG)
|
||||
if (instr.argument != 0 || instr.input0 == VM_INPUT_ARG)
|
||||
{
|
||||
if(instr.output == VM_OUTPUT_JUMP || instr.output == VM_OUTPUT_JUMPR)
|
||||
fprintf(f, " 0x%X", instr.argument);
|
||||
|
@ -268,6 +268,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
fprintf(
|
||||
stderr, "Invalid version %s: %d.%d\n",
|
||||
fileName,
|
||||
fileHeader.majorVersion, fileHeader.minorVersion);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C685C35A-C310-4A9D-AF6F-98CCBD388683}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>expdump</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="expdump.c" />
|
||||
<ClCompile Include="getopt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="exp.h" />
|
||||
<ClInclude Include="getopt.h" />
|
||||
<ClInclude Include="vm.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,36 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Quelldateien">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Headerdateien">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Ressourcendateien">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="getopt.c">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="expdump.c">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="getopt.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="exp.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vm.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -28,12 +28,20 @@ int main(int argc, char **argv)
|
|||
char const *codefileName = NULL;
|
||||
char const *datafileName = NULL;
|
||||
int memsize = 65536;
|
||||
int codeStart = 0;
|
||||
int dataStart = 0;
|
||||
opterr = 0;
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, "c:d:m:o:")) != -1)
|
||||
while ((c = getopt(argc, argv, "C:D:c:d:m:o:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'C':
|
||||
codeStart = atoi(optarg);
|
||||
break;
|
||||
case 'D':
|
||||
dataStart = atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
memsize = atoi(optarg);
|
||||
if (memsize <= 0) {
|
||||
|
@ -97,12 +105,15 @@ int main(int argc, char **argv)
|
|||
|
||||
DEBUG_VAL(fileHeader.posSections);
|
||||
|
||||
expsection_t codeSection = { 0, 0 };
|
||||
expsection_t codeSection = { 0, codeStart };
|
||||
strcpy(codeSection.name, ".code");
|
||||
|
||||
expsection_t dataSection = { 1, 0 };
|
||||
expsection_t dataSection = { 1, dataStart };
|
||||
strcpy(dataSection.name, ".data");
|
||||
|
||||
DEBUG_VAL(codeSection.base);
|
||||
DEBUG_VAL(dataSection.base);
|
||||
|
||||
if (codefileName != NULL)
|
||||
fwrite(&codeSection, sizeof(expsection_t), 1, f);
|
||||
if (datafileName != NULL)
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{2A84DC2E-34B9-48A5-8DE5-170C367B471E}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>libvm</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<ProjectName>explink</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StructMemberAlignment>1Byte</StructMemberAlignment>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StructMemberAlignment>1Byte</StructMemberAlignment>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StructMemberAlignment>1Byte</StructMemberAlignment>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StructMemberAlignment>1Byte</StructMemberAlignment>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="explink.c" />
|
||||
<ClCompile Include="getopt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="getopt.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Quelldateien">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Headerdateien">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Ressourcendateien">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="getopt.c">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="explink.c">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="getopt.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
259
libvm/vm.c
Normal file
259
libvm/vm.c
Normal file
|
@ -0,0 +1,259 @@
|
|||
#include "vm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static uint32_t cmd_copy(cmdinput_t *info)
|
||||
{
|
||||
return info->input0;
|
||||
}
|
||||
|
||||
static uint32_t cmd_load(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
switch(info->info) {
|
||||
case 2:
|
||||
result |=(uint32_t)(vm_read_byte(p, info->input0+3))<<24;
|
||||
result |=(uint32_t)(vm_read_byte(p, info->input0+2))<<16;
|
||||
case 1:
|
||||
result |=(uint32_t)(vm_read_byte(p, info->input0+1))<< 8;
|
||||
case 0:
|
||||
result |=(uint32_t)(vm_read_byte(p, info->input0+0))<< 0;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t cmd_store(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
switch(info->info) {
|
||||
case 2:
|
||||
vm_write_byte(p, info->input0+3, info->input1>>24);
|
||||
vm_write_byte(p, info->input0+2, info->input1>>16);
|
||||
case 1:
|
||||
vm_write_byte(p, info->input0+1, info->input1>>8);
|
||||
case 0:
|
||||
vm_write_byte(p, info->input0, info->input1);
|
||||
break;
|
||||
}
|
||||
return info->input1;
|
||||
}
|
||||
|
||||
static uint32_t cmd_spget(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
return p->stackPointer;
|
||||
}
|
||||
|
||||
static uint32_t cmd_spset(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
return p->stackPointer = info->input0;
|
||||
}
|
||||
|
||||
static uint32_t cmd_bpget(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
return p->basePointer;
|
||||
}
|
||||
|
||||
static uint32_t cmd_bpset(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
return p->basePointer = info->input0;
|
||||
}
|
||||
|
||||
static uint32_t cmd_cpget(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
return p->codePointer + info->info;
|
||||
}
|
||||
|
||||
static inline int16_t makeSigned(uint16_t val)
|
||||
{
|
||||
return *((int16_t*)&val);
|
||||
}
|
||||
|
||||
static uint32_t cmd_get(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
return p->stack[p->basePointer + makeSigned(info->input0)];
|
||||
}
|
||||
|
||||
static uint32_t cmd_set(spu_t *p, cmdinput_t *info)
|
||||
{
|
||||
return p->stack[p->basePointer + makeSigned(info->input0)] = info->input1;
|
||||
}
|
||||
|
||||
static uint32_t cmd_math(cmdinput_t *info)
|
||||
{
|
||||
switch(info->info)
|
||||
{
|
||||
// IMPORTANT:
|
||||
// input1 - input0 because then input0 can be a fixed value
|
||||
#define S(name, op) case name: return info->input1 op info->input0; break;
|
||||
S(VM_MATH_ADD, +)
|
||||
S(VM_MATH_SUB, -)
|
||||
S(VM_MATH_MUL, *)
|
||||
S(VM_MATH_DIV, /)
|
||||
S(VM_MATH_MOD, %)
|
||||
S(VM_MATH_AND, &)
|
||||
S(VM_MATH_OR, |)
|
||||
S(VM_MATH_XOR, ^)
|
||||
#undef S
|
||||
case VM_MATH_NOT: return ~info->input0; break;
|
||||
default: vm_assert(0, "Invalid instruction: MATH command not defined."); return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int vm_step_process(spu_t *process)
|
||||
{
|
||||
vm_assert(process != NULL, "process must not be NULL.");
|
||||
instruction_t instr = process->code[process->codePointer++];
|
||||
|
||||
int exec = 1;
|
||||
switch(instr.execZ)
|
||||
{
|
||||
case VM_EXEC_X:
|
||||
/* Don't modify execution. */
|
||||
break;
|
||||
case VM_EXEC_0:
|
||||
if((process->flags & VM_FLAG_Z) != 0)
|
||||
exec = 0;
|
||||
break;
|
||||
case VM_EXEC_1:
|
||||
if((process->flags & VM_FLAG_Z) == 0)
|
||||
exec = 0;
|
||||
break;
|
||||
default:
|
||||
vm_assert(0, "Invalid instruction: execZ undefined.");
|
||||
break;
|
||||
}
|
||||
|
||||
switch(instr.execN)
|
||||
{
|
||||
case VM_EXEC_X:
|
||||
/* Don't modify execution. */
|
||||
break;
|
||||
case VM_EXEC_0:
|
||||
if((process->flags & VM_FLAG_N) != 0)
|
||||
exec = 0;
|
||||
break;
|
||||
case VM_EXEC_1:
|
||||
if((process->flags & VM_FLAG_N) == 0)
|
||||
exec = 0;
|
||||
break;
|
||||
default:
|
||||
vm_assert(0, "Invalid instruction: execN undefined.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Only do further instruction execution when
|
||||
// the execution condition is met.
|
||||
if(exec)
|
||||
{
|
||||
cmdinput_t info = { 0 };
|
||||
switch(instr.input0)
|
||||
{
|
||||
case VM_INPUT_ZERO: info.input0 = 0; break;
|
||||
case VM_INPUT_POP: info.input0 = vm_pop(process); break;
|
||||
case VM_INPUT_PEEK: info.input0 = vm_peek(process); break;
|
||||
case VM_INPUT_ARG: info.input0 = instr.argument; break;
|
||||
default: vm_assert(0, "Invalid instruction: input0 undefined.");
|
||||
}
|
||||
|
||||
switch(instr.input1)
|
||||
{
|
||||
case VM_INPUT_ZERO: info.input1 = 0; break;
|
||||
case VM_INPUT_POP: info.input1 = vm_pop(process); break;
|
||||
default: vm_assert(0, "Invalid instruction: input1 undefined.");
|
||||
}
|
||||
|
||||
info.info = instr.cmdinfo;
|
||||
|
||||
uint32_t output = -1;
|
||||
switch(instr.command)
|
||||
{
|
||||
case VM_CMD_COPY: output = cmd_copy(&info); break;
|
||||
case VM_CMD_STORE: output = cmd_store(process, &info); break;
|
||||
case VM_CMD_LOAD: output = cmd_load(process, &info); break;
|
||||
case VM_CMD_MATH: output = cmd_math(&info); break;
|
||||
case VM_CMD_SYSCALL: output = vm_syscall(process, &info); break;
|
||||
case VM_CMD_HWIO: output = vm_hwio(process, &info); break;
|
||||
case VM_CMD_SPGET: output = cmd_spget(process, &info); break;
|
||||
case VM_CMD_SPSET: output = cmd_spset(process, &info); break;
|
||||
case VM_CMD_BPGET: output = cmd_bpget(process, &info); break;
|
||||
case VM_CMD_BPSET: output = cmd_bpset(process, &info); break;
|
||||
case VM_CMD_CPGET: output = cmd_cpget(process, &info); break;
|
||||
case VM_CMD_GET: output = cmd_get(process, &info); break;
|
||||
case VM_CMD_SET: output = cmd_set(process, &info); break;
|
||||
default: vm_assert(0, "Invalid instruction: command undefined.");
|
||||
}
|
||||
|
||||
switch(instr.flags)
|
||||
{
|
||||
case VM_FLAG_YES:
|
||||
process->flags = 0;
|
||||
if(output == 0)
|
||||
process->flags |= VM_FLAG_Z;
|
||||
else if((output & (1<<31)) != 0)
|
||||
process->flags |= VM_FLAG_N;
|
||||
break;
|
||||
case VM_FLAG_NO: break;
|
||||
default:
|
||||
vm_assert(0, "Invalid instruction: invalid flags.");
|
||||
}
|
||||
|
||||
switch(instr.output)
|
||||
{
|
||||
case VM_OUTPUT_DISCARD: break;
|
||||
case VM_OUTPUT_PUSH: vm_push(process, output); break;
|
||||
case VM_OUTPUT_JUMP: process->codePointer = output; break;
|
||||
case VM_OUTPUT_JUMPR:
|
||||
process->codePointer += *((int32_t*)&output);
|
||||
break;
|
||||
default:
|
||||
vm_assert(0, "Invalid instruction: invalid output.");
|
||||
}
|
||||
}
|
||||
|
||||
return process->codePointer < process->codeLength;
|
||||
}
|
||||
|
||||
void vm_push(spu_t *process, uint32_t value)
|
||||
{
|
||||
vm_assert(process != NULL, "process must not be NULL.");
|
||||
vm_assert(process->stackPointer < VM_STACKSIZE, "Stack overflow");
|
||||
process->stack[++process->stackPointer] = value;
|
||||
}
|
||||
|
||||
uint32_t vm_pop(spu_t *process)
|
||||
{
|
||||
vm_assert(process != NULL, "process must not be NULL.");
|
||||
uint32_t psp = process->stackPointer;
|
||||
uint32_t val = process->stack[process->stackPointer--];
|
||||
|
||||
// Underflow check works because unsigned overflow is defined ;)
|
||||
vm_assert(psp >= process->stackPointer, "Stack underflow");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t vm_peek(spu_t *process)
|
||||
{
|
||||
vm_assert(process != NULL, "process must not be NULL.");
|
||||
return process->stack[process->stackPointer];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t vm_read_byte(spu_t *process, uint32_t address)
|
||||
{
|
||||
vm_assert(process != NULL, "process must not be NULL.");
|
||||
address -= process->memoryBase;
|
||||
vm_assert(address < process->memorySize, "Out of memory.");
|
||||
return ((uint8_t*)process->memory)[address];
|
||||
}
|
||||
|
||||
void vm_write_byte(spu_t *process, uint32_t address, uint8_t value)
|
||||
{
|
||||
vm_assert(process != NULL, "process must not be NULL.");
|
||||
address -= process->memoryBase;
|
||||
vm_assert(address < process->memorySize, "Out of memory.");
|
||||
((uint8_t*)process->memory)[address] = value;
|
||||
}
|
Loading…
Reference in a new issue