all repos — 3ByteBadVM @ 26457be29042435c16fecfca6a769791e0de512b

3ByteBadVM

src/vm.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
/* x1phosura 2021 */

#pragma once                    // WAAAAAY better than a dumb header guard ;)

#define RAM_SIZE   16384        // highest it can be given 16-bit addresses
#define STACK_LIM  64


enum instructions {
	HALT  = 0,
	PUSH  = 1,
	POP   = 2,
	PUSHI = 3,
	LDLR  = 4,
	STLR  = 5,
	SETI  = 6,
	DUP   = 7,
	ADD   = 8,
	SUB   = 9,
	XOR   = 10,
	CALL  = 11,
	RET   = 12,
	JMP   = 13,
	BEQ   = 14,
	BNQ   = 15,
	// every opcode 0x10-0xfe is basically just a NOP just to be annoying
	NOP = 0xff
};


struct CPU {
	uint16_t pc;
	uint16_t lr;
	uint16_t sp;
	//uint16_t a;
	uint8_t stack[STACK_LIM];
	enum state_t {STOPPED, RUNNING, PAUSED} state;
};


#ifdef TRACE    // TRACE
struct TRACE_T {
	uint16_t breakpoint;
	enum tmode_t {STEP, CONT} mode;
};

void print_op_decoded(uint8_t i[3], bool pargs);
void print_vm_registers(struct CPU *cpu);
void print_vm_stack(struct CPU *cpu);
void print_vm_memory(uint8_t *mem, uint16_t start_addr, uint16_t num_bytes);
void vm_trace(struct CPU *cpu, uint8_t *mem, struct TRACE_T *tstate);
#endif          // TRACE

uint16_t vm_do_instruction(struct CPU *cpu, uint8_t *mem, uint8_t instr[3]);

void vm_run(struct CPU *cpu, uint8_t *mem);
void vm_init(struct CPU *cpu, uint8_t *mem, uint8_t *memimage,
                                                             uint16_t imgsize);