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/
|
GeneratedArtifacts/
|
||||||
_Pvt_Extensions/
|
_Pvt_Extensions/
|
||||||
ModelManifest.xml
|
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)
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 *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)
|
||||||
|
|
|
@ -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