Adds windows build script, adds section start to explink, improves decompilation with expdump.

This commit is contained in:
Felix Queißner 2016-06-30 11:22:32 +02:00
parent 47b608f2c8
commit 5d1d274afd
11 changed files with 540 additions and 423 deletions

6
.gitignore vendored
View file

@ -210,3 +210,9 @@ FakesAssemblies/
GeneratedArtifacts/ GeneratedArtifacts/
_Pvt_Extensions/ _Pvt_Extensions/
ModelManifest.xml ModelManifest.xml
*.exe
*.lib
*.dll
SDL-1.2.15/

21
libvm/build.bat Normal file
View 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
View 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(&section, 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;
}

View file

@ -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

View file

@ -125,7 +125,7 @@ void disassemble(instruction_t *list, uint32_t count, uint32_t base, FILE *f)
if (knownInstruction != NULL) if (knownInstruction != NULL)
{ {
fprintf(f, "%s", knownInstruction->name); 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) if(instr.output == VM_OUTPUT_JUMP || instr.output == VM_OUTPUT_JUMPR)
fprintf(f, " 0x%X", instr.argument); fprintf(f, " 0x%X", instr.argument);
@ -268,6 +268,7 @@ int main(int argc, char **argv)
{ {
fprintf( fprintf(
stderr, "Invalid version %s: %d.%d\n", stderr, "Invalid version %s: %d.%d\n",
fileName,
fileHeader.majorVersion, fileHeader.minorVersion); fileHeader.majorVersion, fileHeader.minorVersion);
continue; continue;
} }

View file

@ -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>

View file

@ -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>

View file

@ -28,12 +28,20 @@ int main(int argc, char **argv)
char const *codefileName = NULL; char const *codefileName = NULL;
char const *datafileName = NULL; char const *datafileName = NULL;
int memsize = 65536; int memsize = 65536;
int codeStart = 0;
int dataStart = 0;
opterr = 0; opterr = 0;
int c; 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) switch (c)
{ {
case 'C':
codeStart = atoi(optarg);
break;
case 'D':
dataStart = atoi(optarg);
break;
case 'm': case 'm':
memsize = atoi(optarg); memsize = atoi(optarg);
if (memsize <= 0) { if (memsize <= 0) {
@ -97,12 +105,15 @@ int main(int argc, char **argv)
DEBUG_VAL(fileHeader.posSections); DEBUG_VAL(fileHeader.posSections);
expsection_t codeSection = { 0, 0 }; expsection_t codeSection = { 0, codeStart };
strcpy(codeSection.name, ".code"); strcpy(codeSection.name, ".code");
expsection_t dataSection = { 1, 0 }; expsection_t dataSection = { 1, dataStart };
strcpy(dataSection.name, ".data"); strcpy(dataSection.name, ".data");
DEBUG_VAL(codeSection.base);
DEBUG_VAL(dataSection.base);
if (codefileName != NULL) if (codefileName != NULL)
fwrite(&codeSection, sizeof(expsection_t), 1, f); fwrite(&codeSection, sizeof(expsection_t), 1, f);
if (datafileName != NULL) if (datafileName != NULL)

View file

@ -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>

View file

@ -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
View 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;
}