157 lines
5.9 KiB
C
157 lines
5.9 KiB
C
#ifndef ZRL_OPCODES_H
|
|
#define ZRL_OPCODES_H
|
|
|
|
#include "common.h"
|
|
|
|
typedef union value_u {
|
|
int32_t i; /* Integers */
|
|
float f; /* Float */
|
|
uint32_t u; /* Unsigned integers, also used for pointer address */
|
|
char c[4]; /* 4 Byte char array for string packing */
|
|
} Value;
|
|
|
|
typedef struct slice_s {
|
|
uint32_t start;
|
|
uint32_t end;
|
|
} Slice;
|
|
|
|
#define MAX_REGS 32
|
|
typedef struct frame_s {
|
|
Value registers[MAX_REGS]; /* R0-R31 */
|
|
uint32_t rp; /* register pointer (last unused) */
|
|
Slice allocated; /* start and end of global allocated block */
|
|
} Frame;
|
|
|
|
typedef struct screen_t {
|
|
uint8_t width;
|
|
uint8_t height;
|
|
Slice allocated;
|
|
Value *buffer;
|
|
} Screen;
|
|
|
|
typedef struct mouse_t {
|
|
uint32_t x;
|
|
uint32_t y;
|
|
uint8_t btn1;
|
|
uint8_t btn2;
|
|
uint8_t btn3;
|
|
} Mouse;
|
|
|
|
typedef struct keyboard_t {
|
|
uint32_t length;
|
|
const uint8_t *keys;
|
|
} Keyboard;
|
|
|
|
typedef union device_u {
|
|
uint8_t type;
|
|
Screen s;
|
|
Mouse m;
|
|
Keyboard k;
|
|
/* File f; */
|
|
/* Tunnel t; */
|
|
} Device;
|
|
|
|
#define MEMORY_SIZE 65536
|
|
#define CODE_SIZE 8192
|
|
#define FRAMES_SIZE 128
|
|
#define STACK_SIZE 256
|
|
#define DEVICES_SIZE 8
|
|
typedef struct vm_s {
|
|
uint32_t pc; /* program counter */
|
|
uint32_t cp; /* code pointer (last allocated opcode) */
|
|
uint32_t fp; /* frame pointer (current frame) */
|
|
uint32_t sp; /* stack pointer (top of stack) */
|
|
uint32_t rp; /* return stack pointer (top of stack) */
|
|
uint32_t mp; /* memory pointer (last allocated value) */
|
|
uint32_t dp; /* device pointer (last allocated device) */
|
|
uint8_t devices_size;
|
|
Device devices[DEVICES_SIZE];
|
|
uint32_t frames_size;
|
|
Frame frames[FRAMES_SIZE]; /* function call frames */
|
|
uint32_t stack_size;
|
|
Value stack[STACK_SIZE]; /* main stack */
|
|
uint32_t return_stack_size;
|
|
Value return_stack[STACK_SIZE]; /* return stack (for recursion) */
|
|
uint32_t code_size;
|
|
Value code[CODE_SIZE]; /* code block */
|
|
uint32_t memory_size;
|
|
Value memory[MEMORY_SIZE]; /* memory block */
|
|
} VM;
|
|
|
|
typedef enum {
|
|
OP_HALT, /* halt : terminate execution */
|
|
OP_LOADI, /* lodi : dest = next memory location as int */
|
|
OP_LOADU, /* lodu : dest = next memory location as uint */
|
|
OP_LOADF, /* lodf : dest = next memory location as float */
|
|
OP_STOREI, /* stri : next memory location = src1 as int */
|
|
OP_STOREU, /* stru : next memory location = src1 as uint */
|
|
OP_STOREF, /* strf : next memory location = src1 as float */
|
|
OP_PUSHI, /* pshi : push int from register onto the stack */
|
|
OP_PUSHU, /* pshu : push uint from register onto the stack */
|
|
OP_PUSHF, /* pshf : push float from register onto the stack */
|
|
OP_PUSHS, /* pshs : push str ref from register onto the stack and copy str */
|
|
OP_POPI, /* popi : pop int from stack onto the register */
|
|
OP_POPU, /* popu : pop uint from stack onto the register */
|
|
OP_POPF, /* popf : pop float from stack onto the register */
|
|
OP_POPS, /* pops : pop str ref from stack and move/copy to register */
|
|
OP_ADD_INT, /* addi : dest = src1 + src2 */
|
|
OP_SUB_INT, /* subi : dest = src1 - src2 */
|
|
OP_MUL_INT, /* muli : dest = src1 * src2 */
|
|
OP_DIV_INT, /* divi : dest = src1 / src2 */
|
|
OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */
|
|
OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/
|
|
OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */
|
|
OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */
|
|
OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/
|
|
OP_INT_TO_REAL, /* itor : dest = src1 as f32 */
|
|
OP_ADD_UINT, /* addu : dest = src1 + src2 */
|
|
OP_SUB_UINT, /* subu : dest = src1 - src2 */
|
|
OP_MUL_UINT, /* mulu : dest = src1 * src2 */
|
|
OP_DIV_UINT, /* divu : dest = src1 / src2 */
|
|
OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */
|
|
OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/
|
|
OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */
|
|
OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */
|
|
OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/
|
|
OP_UINT_TO_REAL, /* utor : dest = src1 as f32 */
|
|
OP_ADD_REAL, /* addr : dest = src1 + src2 */
|
|
OP_SUB_REAL, /* subr : dest = src1 - src2 */
|
|
OP_MUL_REAL, /* mulr : dest = src1 * src2 */
|
|
OP_DIV_REAL, /* divr : dest = src1 / src2 */
|
|
OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */
|
|
OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */
|
|
OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */
|
|
OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */
|
|
OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */
|
|
OP_REAL_TO_INT, /* rtoi : dest = src1 as int */
|
|
OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */
|
|
OP_REG_MOV, /* rmov : dest = src1 */
|
|
OP_REG_SWAP, /* rswp : dest = src1, src1 = dest */
|
|
OP_JMP, /* jump : jump to address src1 unconditionally */
|
|
OP_CALL, /* call : creates a new frame */
|
|
OP_RETURN, /* retn : returns from a frame to the parent frame */
|
|
OP_INT_TO_STRING, /* itos : dest = src1 as str */
|
|
OP_UINT_TO_STRING, /* utos : dest = src1 as str */
|
|
OP_REAL_TO_STRING, /* rtos : dest = src1 as str */
|
|
OP_READ_STRING, /* gets : dest = gets as str */
|
|
OP_PRINT_STRING, /* puts : write src1 to stdout */
|
|
OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */
|
|
OP_NOT, /* not : dest = not src1 */
|
|
OP_MEM_ALLOC, /* alloc : dest = &ptr */
|
|
OP_MEM_SWAP, /* swap : &dest = &src1, &src1 = &dest */
|
|
OP_MEM_MOV, /* mov : &dest = &src1 */
|
|
} Opcode;
|
|
|
|
typedef enum {
|
|
SCREEN,
|
|
MOUSE,
|
|
KEYBOARD,
|
|
CONTROLLER,
|
|
AUDIO,
|
|
} Devicecode;
|
|
|
|
/* defines a uint32 opcode */
|
|
#define OP(opcode, a, b, c) ((opcode << 24) | (a << 16) | (b << 8) | c)
|
|
|
|
#endif
|