2016-05-19 10:42:39 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
|
|
|
#if defined(__cplusplus)
|
|
|
|
extern "C" {
|
2016-05-30 17:48:07 +00:00
|
|
|
#define _Static_assert static_assert
|
2016-05-19 10:42:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !defined(VM_STACKSIZE)
|
2016-05-22 15:17:30 +00:00
|
|
|
#define VM_STACKSIZE 512
|
2016-05-19 10:42:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Binary Encoding : (enabled, value)
|
|
|
|
#define VM_EXEC_X 0
|
|
|
|
#define VM_EXEC_0 2
|
|
|
|
#define VM_EXEC_1 3
|
|
|
|
|
|
|
|
#define VM_INPUT_ZERO 0
|
|
|
|
#define VM_INPUT_POP 1
|
|
|
|
#define VM_INPUT_PEEK 2
|
|
|
|
#define VM_INPUT_ARG 3
|
|
|
|
|
|
|
|
#define VM_CMD_COPY 0
|
|
|
|
#define VM_CMD_STORE 1
|
|
|
|
#define VM_CMD_LOAD 2
|
|
|
|
#define VM_CMD_GET 3
|
|
|
|
#define VM_CMD_SET 4
|
|
|
|
#define VM_CMD_BPGET 5
|
|
|
|
#define VM_CMD_BPSET 6
|
2016-05-21 19:36:34 +00:00
|
|
|
#define VM_CMD_CPGET 7
|
2016-05-19 10:42:39 +00:00
|
|
|
#define VM_CMD_MATH 8
|
|
|
|
#define VM_CMD_SPGET 9
|
|
|
|
#define VM_CMD_SPSET 10
|
2016-05-21 15:57:13 +00:00
|
|
|
#define VM_CMD_SYSCALL 11
|
|
|
|
#define VM_CMD_HWIO 12
|
2016-05-19 10:42:39 +00:00
|
|
|
|
|
|
|
#define VM_MATH_ADD 0
|
|
|
|
#define VM_MATH_SUB 1
|
|
|
|
#define VM_MATH_MUL 2
|
|
|
|
#define VM_MATH_DIV 3
|
|
|
|
#define VM_MATH_MOD 4
|
|
|
|
#define VM_MATH_AND 5
|
|
|
|
#define VM_MATH_OR 6
|
|
|
|
#define VM_MATH_XOR 7
|
|
|
|
#define VM_MATH_NOT 8
|
|
|
|
#define VM_MATH_ROL 9
|
|
|
|
#define VM_MATH_ROR 10
|
|
|
|
#define VM_MATH_ASL 11
|
|
|
|
#define VM_MATH_ASR 12
|
|
|
|
#define VM_MATH_SHL 13
|
|
|
|
#define VM_MATH_SHR 14
|
|
|
|
|
|
|
|
#define VM_FLAG_NO 0
|
2016-05-19 12:09:15 +00:00
|
|
|
#define VM_FLAG_YES 1
|
2016-05-19 10:42:39 +00:00
|
|
|
|
|
|
|
#define VM_OUTPUT_DISCARD 0
|
|
|
|
#define VM_OUTPUT_PUSH 1
|
|
|
|
#define VM_OUTPUT_JUMP 2
|
2016-05-30 17:48:07 +00:00
|
|
|
#define VM_OUTPUT_JUMPR 3
|
2016-05-19 10:42:39 +00:00
|
|
|
|
2016-05-19 12:09:15 +00:00
|
|
|
#define VM_FLAG_Z (1<<0)
|
|
|
|
#define VM_FLAG_N (1<<1)
|
|
|
|
|
2016-05-19 10:42:39 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
unsigned int execZ : 2;
|
|
|
|
unsigned int execN : 2;
|
|
|
|
unsigned int input0 : 2;
|
|
|
|
unsigned int input1 : 1;
|
|
|
|
unsigned int command : 6;
|
|
|
|
unsigned int cmdinfo : 16;
|
|
|
|
unsigned int flags : 1;
|
|
|
|
unsigned int output : 2;
|
|
|
|
uint32_t argument;
|
|
|
|
} __attribute__ ((packed)) Instruction;
|
|
|
|
|
|
|
|
_Static_assert(sizeof(Instruction) == 8, "Instruction must be 8 bytes large.");
|
|
|
|
_Static_assert(offsetof(Instruction, argument) == 4, "Argument must be must be 8 bytes large.");
|
|
|
|
|
2016-05-19 11:19:38 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
Instruction *code;
|
|
|
|
uint32_t length;
|
|
|
|
} Module;
|
|
|
|
|
2016-05-21 17:17:08 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t pageSize;
|
|
|
|
uint32_t length;
|
|
|
|
uint8_t **pages;
|
|
|
|
} VirtualMemoryMap;
|
|
|
|
|
2016-05-19 10:42:39 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2016-05-19 11:19:38 +00:00
|
|
|
Module *module;
|
2016-05-21 15:57:13 +00:00
|
|
|
void *tag;
|
2016-05-19 11:19:38 +00:00
|
|
|
|
2016-05-19 10:42:39 +00:00
|
|
|
uint32_t codePointer;
|
|
|
|
uint32_t stackPointer;
|
|
|
|
uint32_t basePointer;
|
|
|
|
uint32_t flags;
|
|
|
|
|
|
|
|
uint32_t stack[VM_STACKSIZE];
|
2016-05-21 17:17:08 +00:00
|
|
|
|
|
|
|
VirtualMemoryMap mmap;
|
2016-05-19 10:42:39 +00:00
|
|
|
} Process;
|
|
|
|
|
2016-05-21 15:57:13 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t input0;
|
|
|
|
uint32_t input1;
|
|
|
|
uint32_t argument;
|
|
|
|
uint32_t additional;
|
|
|
|
|
|
|
|
uint32_t output;
|
|
|
|
} CommandInfo;
|
|
|
|
|
2016-05-19 11:19:38 +00:00
|
|
|
/**
|
|
|
|
* @brief Steps a given process.
|
|
|
|
*
|
|
|
|
* Executes a single instruction and processes input and output.
|
|
|
|
*
|
|
|
|
* @param process The process to be stepped.
|
|
|
|
* @returns 1 if the process is still running or 0 if the process is terminated.
|
|
|
|
*/
|
|
|
|
int vm_step_process(Process *process);
|
|
|
|
|
2016-05-19 12:09:15 +00:00
|
|
|
/**
|
|
|
|
* @brief Pushes a value onto the process' stack.
|
|
|
|
*/
|
2016-05-19 11:19:38 +00:00
|
|
|
void vm_push(Process *process, uint32_t value);
|
|
|
|
|
2016-05-19 12:09:15 +00:00
|
|
|
/**
|
|
|
|
* @brief Pops a value from the process' stack.
|
|
|
|
*/
|
2016-05-19 11:19:38 +00:00
|
|
|
uint32_t vm_pop(Process *process);
|
2016-05-19 10:42:39 +00:00
|
|
|
|
2016-05-19 12:09:15 +00:00
|
|
|
/**
|
|
|
|
* @brief Returns the top value of the process' stack.
|
|
|
|
*/
|
2016-05-19 11:19:38 +00:00
|
|
|
uint32_t vm_peek(Process *process);
|
2016-05-19 10:42:39 +00:00
|
|
|
|
2016-05-21 17:26:08 +00:00
|
|
|
/**
|
|
|
|
* Reads a byte from process memory.
|
|
|
|
* @arg process
|
|
|
|
* @arg address The address to read from.
|
|
|
|
*/
|
|
|
|
uint8_t vm_read_byte(Process *process, uint32_t address);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Writes a byte to process memory.
|
|
|
|
* @arg process
|
|
|
|
* @arg address The address to read from.
|
|
|
|
*/
|
|
|
|
void vm_write_byte(Process *process, uint32_t address, uint8_t value);
|
2016-05-21 15:57:13 +00:00
|
|
|
|
|
|
|
// The following functions need to be host-implemented.
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An assertion the VM does.
|
|
|
|
* @param assertion If zero, the assertion failed.
|
|
|
|
* @param msg The message that should be shown when the assertion fails.
|
|
|
|
*/
|
2016-05-19 11:19:38 +00:00
|
|
|
void vm_assert(int assertion, const char *msg);
|
2016-05-19 10:42:39 +00:00
|
|
|
|
2016-05-21 15:57:13 +00:00
|
|
|
/**
|
|
|
|
* The hosts syscall implementation.
|
|
|
|
* @param process The process that calls the syscall.
|
|
|
|
* @param info Additional information for the syscall. Contains arguments and results.
|
|
|
|
*/
|
|
|
|
void vm_syscall(Process *process, CommandInfo *info);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
void vm_hwio(Process *process, CommandInfo *info);
|
|
|
|
|
2016-05-19 10:42:39 +00:00
|
|
|
#if defined(__cplusplus)
|
|
|
|
}
|
2016-05-30 17:48:07 +00:00
|
|
|
#undef _Static_assert
|
2016-05-19 10:42:39 +00:00
|
|
|
#endif
|