-
Notifications
You must be signed in to change notification settings - Fork 2
/
toyvm.h
115 lines (95 loc) · 3.19 KB
/
toyvm.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#ifndef TOYVM_H
#define TOYVM_H
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
enum {
/* Arithmetics */
ADD = 0x01,
NEG = 0x02,
MUL = 0x03,
DIV = 0x04,
MOD = 0x05,
/* Conditionals */
CMP = 0x10,
JA = 0x11,
JE = 0x12,
JB = 0x13,
JMP = 0x14,
/* Subroutines */
CALL = 0x20,
RET = 0x21,
/* Moving data */
LOAD = 0x30,
STORE = 0x31,
CONST = 0x32,
RLOAD = 0x33,
RSTORE = 0x34,
/* Auxiliary */
HALT = 0x40,
INT = 0x41,
NOP = 0x42,
/* Stack */
PUSH = 0x50,
PUSH_ALL = 0x51,
POP = 0x52,
POP_ALL = 0x53,
LSP = 0x54,
/* Registers */
REG1 = 0x00,
REG2 = 0x01,
REG3 = 0x02,
REG4 = 0x03,
/* Interupts */
INTERRUPT_PRINT_INTEGER = 0x01,
INTERRUPT_PRINT_STRING = 0x02,
/* Miscellaneous */
N_REGISTERS = 4,
OPCODE_MAP_SIZE = 256,
};
typedef struct VM_CPU {
int32_t registers[N_REGISTERS];
int32_t program_counter;
int32_t stack_pointer;
struct {
uint8_t BAD_INSTRUCTION : 1;
uint8_t STACK_UNDERFLOW : 1;
uint8_t STACK_OVERFLOW : 1;
uint8_t INVALID_REGISTER_INDEX : 1;
uint8_t BAD_ACCESS : 1;
uint8_t COMPARISON_BELOW : 1;
uint8_t COMPARISON_EQUAL : 1;
uint8_t COMPARISON_ABOVE : 1;
} status;
} VM_CPU;
typedef struct TOYVM {
uint8_t* memory;
int32_t memory_size;
int32_t stack_limit;
VM_CPU cpu;
size_t opcode_map[OPCODE_MAP_SIZE];
} TOYVM;
/*******************************************************************************
* Initializes the virtual machine with RAM memory of length 'memory_size' and *
* the stack fence at 'stack_limit'.
*******************************************************************************/
void InitializeVM(TOYVM* vm, int32_t memory_size, int32_t stack_limit);
/*******************************************************************************
* Writes 'size' bytes to the memory of the machine. The write begins from the *
* beginning of the memory tape. *
*******************************************************************************/
void WriteVMMemory(TOYVM* vm, uint8_t* mem, size_t size);
/*******************************************************************************
* Writes a single word 'value' (32-bit signed integer) at address 'address'. *
*******************************************************************************/
void WriteWord(TOYVM* vm, int32_t address, int32_t value);
/*******************************************************************************
* Prints the status of the machine to stdout. *
*******************************************************************************/
void PrintStatus(TOYVM* vm);
/*******************************************************************************
* Runs the virtual machine. *
*******************************************************************************/
void RunVM(TOYVM* vm);
#endif /* TOYVM_H */