From 157a516ad99a05f14778680e376f20cae7d88387 Mon Sep 17 00:00:00 2001 From: bylex Date: Wed, 25 Sep 2024 08:24:18 +0200 Subject: [PATCH 1/1] Add initial opcodes file --- opcodes.h | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 opcodes.h diff --git a/opcodes.h b/opcodes.h new file mode 100644 index 0000000..1142153 --- /dev/null +++ b/opcodes.h @@ -0,0 +1,166 @@ +/* + * operation codes with description + * register size is 2 bytes + * + * nop, 1 byte length - instruction - no operation + * + * inc, 3 byte length - instruction + dest register + source register - increment dest register by source register + * dec, 3 byte length - instruction + dest register + source register - decrement dest register by source register + * + * lod, 4 byte length - instruction + dest register + source address - load 2 bytes from memory to register + * ldl, 4 byte length - instruction + dest register + number literal - load 2 bytes from instruction to register + * sav, 4 byte length - instruction + dest address + source register - save 2 bytes from register to memory + * swp, 4 byte length - instruction + address + register - swap 2 bytes between register and memory + * + * jmp, 2 byte length - instruction + register - jump to address in memory + * jez, 4 byte length - instruction + cond register + address - conditional jump to address in memory, if untrue acts as nop + * + * hlt, 1 byte length - instruction - halts execution + * + * pts, 2 byte length - instruction + source register - puts a value on the stack + * pfs, 2 byte length - instruction + dest register - pulls a value from the stack + * stack is 256 values long, 16 bit values + * + * TODO: figure out input/output + * + * wex, 2 byte length - instruction + source register - write 2 bytes to external output(stdout) + * rex, 2 byte length - instruction + dest register - read from external(stdin) - blocks execution until 2 bytes are read + * + * all instructions are padded to 4 bytes + */ + +#include +#include + +extern uint16_t regs[256]; +extern uint16_t mem[65536]; + +extern uint16_t stack[256]; +extern uint8_t stack_pointer; + +extern uint16_t current_instruction; // what location is currently being executed +extern bool halted; // is the execution halted? +extern uint8_t halted_reason; + +void nop(uint8_t unused_1, uint8_t unused_2, uint8_t unused_3) +{ + current_instruction += 2; + return; +} + + + +void inc(uint8_t dest_reg, uint8_t source_reg, uint8_t unused_1) +{ + regs[dest_reg] = regs[dest_reg] + regs[source_reg]; + current_instruction += 2; + return; +} + +void dec(uint8_t dest_reg, uint8_t source_reg, uint8_t unused_1) +{ + regs[dest_reg] = regs[dest_reg] - regs[source_reg]; + current_instruction += 2; + return; +} + + +// loads addressed byte and the next byte into register +void lod(uint8_t dest_reg, uint8_t source_addr_1, uint8_t source_addr_2) +{ + uint16_t source_addr = (uint16_t)source_addr_1 << 8 | source_addr_2; + regs[dest_reg] = mem[source_addr]; + current_instruction += 2; + return; +} + +void ldl(uint8_t dest_reg, uint8_t num_literal_1, uint8_t num_literal_2) +{ + uint16_t num_literal = (uint16_t)num_literal_1 << 8 | num_literal_2; + regs[dest_reg] = num_literal; + current_instruction += 2; + return; +} + +void sav(uint8_t dest_addr_1, uint8_t dest_addr_2, uint8_t source_reg) +{ + uint16_t dest_addr = (uint16_t)dest_addr_1 << 8 | dest_addr_2; + mem[dest_addr] = regs[source_reg]; + current_instruction += 2; + return; +} + +void swp(uint8_t addr_1, uint8_t addr_2, uint8_t reg) +{ + uint16_t addr = (uint16_t)addr_1 << 8 | addr_2; + uint16_t temp_storage = regs[reg]; + regs[reg] = mem[addr]; + mem[addr] = regs[reg]; + current_instruction += 2; + return; +} + + + +void jmp(uint8_t addr_1, uint8_t addr_2, uint8_t unused_1) +{ + uint16_t addr = (uint16_t)addr_1 << 8 | addr_2; + current_instruction = addr; + return; +} + +void jez(uint8_t reg, uint8_t addr_1, uint8_t addr_2) +{ + if(regs[reg] == 0) + { + uint16_t addr = (uint16_t)addr_1 << 8 | addr_2; + current_instruction = addr; + } + else + { + current_instruction += 2; + } + return; +} + + + +void hlt(uint8_t unused_1, uint8_t unused_2, uint8_t unused_3) +{ + halted = true; + halted_reason = 1; + return; +} + + + +void pts(uint8_t source_reg, uint8_t unused_1, uint8_t unused_2) +{ + if(stack_pointer == 255) + { + halted = true; // stack has overflowed, halt execution + halted_reason = 2; + } + else + { + stack[stack_pointer++] = regs[source_reg]; + } + return; +} + +void pfs(uint8_t dest_reg, uint8_t unused_1, uint8_t unused_2) +{ + if(stack_pointer == 0) + { + halted = true; // stack has underflowed, halt execution + halted_reason = 3; + } + else + { + regs[dest_reg] = stack[--stack_pointer]; + } + return; +} + +void (*opcodes[16]) (uint8_t, uint8_t, uint8_t) = {nop, inc, dec, lod, ldl, sav, swp, jmp, jez, hlt, pts, pfs}; +char opcodes_names[16][3] = {"nop", "inc", "dec", "lod", "ldl", "sav", "swp", "jmp", "jez", "hlt", "pts", "pfs"}; -- 2.25.1