diff --git a/cpp/emulator.cpp b/cpp/emulator.cpp index 54b8d88..2705e0b 100644 --- a/cpp/emulator.cpp +++ b/cpp/emulator.cpp @@ -10,21 +10,21 @@ int main(int argc, char *argv[]) { std::streamsize bytecode_size; uint8_t * bytecode; - if (argc < 2) { - printf("Usage: %s \n", argv[0]); + if (argc < 3) { + printf("Usage: %s \n", argv[0]); return 1; } /* reading bytecode */ - bytecode_if.open(argv[1], std::ios::binary | std::ios::ate); + bytecode_if.open(argv[2], std::ios::binary | std::ios::ate); bytecode_size = bytecode_if.tellg(); bytecode_if.seekg(0, std::ios::beg); bytecode = new uint8_t[bytecode_size]; bytecode_if.read((char*)bytecode, bytecode_size); - VM vm(bytecode, bytecode_size); + VM vm((uint8_t*)argv[1], bytecode, bytecode_size); vm.run(); vm.status(); return 0; diff --git a/cpp/vm.cpp b/cpp/vm.cpp index 088068c..8996b4d 100644 --- a/cpp/vm.cpp +++ b/cpp/vm.cpp @@ -3,6 +3,36 @@ #include "vmas.h" #include +unsigned rol(unsigned x, int L, int N) { + unsigned lsbs = x & ((1 >> L) - 1); + return (x << L) | (lsbs >> (N - L)); +} + +void VM::defineOpcodes(uint8_t *key) { + uint32_t i, j, keysize; + keysize = strlen((char *)key); + for (i = 0; i < keysize; i++) { + for (j = 0; j < NUM_OPS; j++) { + if (key[i] % 2) { + ops[j].setValue(rol(key[i] ^ ops[j].getValue(), key[i] % 8, 8)); + } else { + ops[j].setValue(rol(key[i] ^ ops[j].getValue(), (key[i] + 1) % 8, 8)); + } + } + } + for (i = 0; i < NUM_OPS; i++) { + for (j = 0; j < NUM_OPS; j++) { + ops[j].setValue(rol(ops[j].getValue(), ops[i].getValue() % 8, 8)); + } + } +#ifdef DBG + DBG_INFO(("OPCODES:\n")); + for (i = 0; i < NUM_OPS; i++) { + DBG_INFO(("%s: 0x%x\n", ops[i].getName(), ops[i].getValue())); + } +#endif + return; +} /* DBG UTILS */ @@ -101,26 +131,31 @@ void VM::status(void) { /* CONSTRUCTORS */ -VM::VM() { +VM::VM(uint8_t *key) { DBG_SUCC(("Creating VM without code.\n")); as.allocate(); - init_regs(); + initVariables(); + defineOpcodes(key); } -VM::VM(uint8_t *code, uint32_t codesize) { +VM::VM(uint8_t *key, uint8_t *code, uint32_t codesize) { DBG_SUCC(("Creating VM with code.\n")); if (as.allocate()) { as.insCode(code, codesize); } - init_regs(); + initVariables(); + defineOpcodes(key); } -void VM::init_regs(void) { - uint8_t i; +void VM::initVariables(void) { + uint32_t i; - for (i = R0; i <= SP; i++) { + for (i = R0; i < NUM_REGS; i++) { this->regs[i] = 0; } + for (i = MOVI; i < NUM_OPS; i++) { + ops[i].setValue(i); + } return; } @@ -217,11 +252,11 @@ void VM::run(void) { exec_movr(); regs[IP] += MOVR_SIZE; break; - case GETM: + case LOAD: exec_getm(); regs[IP] += GETM_SIZE; break; - case PUTM: + case STOR: exec_putm(); regs[IP] += PUTM_SIZE; break; @@ -229,7 +264,7 @@ void VM::run(void) { exec_addi(); regs[IP] += ADDI_SIZE; break; - case HALT: + case SHIT: DBG_INFO(("HALT\n")); finished = true; break; diff --git a/cpp/vm.h b/cpp/vm.h index d795616..698d23b 100644 --- a/cpp/vm.h +++ b/cpp/vm.h @@ -1,6 +1,7 @@ #ifndef VM_H #define VM_H #include "vmas.h" +#include "vmcomp.h" #include #define MOVI_SIZE 4 @@ -8,7 +9,7 @@ #define GETM_SIZE 4 #define PUTM_SIZE 4 #define ADDI_SIZE 4 -enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP }; +enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP, NUM_REGS }; /* MEMORY LOCATIONS AND IMMEDIATES ARE 16 BITS LONG @@ -16,8 +17,8 @@ MEMORY LOCATIONS AND IMMEDIATES ARE 16 BITS LONG enum ins { MOVI, MOVR, - GETM, - PUTM, + LOAD, + STOR, ADDI, ADDR, SUBI, @@ -33,19 +34,31 @@ enum ins { PUSH, POOP, CALL, - HALT, - NOPE + SHIT, + NOPE, + GERM, + NUM_OPS }; class VM { private: + //////////////////////// + // VARIABLES + //////////////////////// + uint16_t regs[0xb]; + VMComponent ops[NUM_OPS]; struct flags { uint8_t zf : 1; uint8_t cf : 1; }; VMAddrSpace as; + //////////////////////// + // FUNCTIONS + /////////////////////// + void initVariables(void); + void defineOpcodes(uint8_t * key); /* DBG UTILS */ @@ -61,9 +74,8 @@ private: bool exec_addi(void); public: - VM(); - VM(uint8_t *code, uint32_t codesize); - void init_regs(void); + VM(uint8_t * key); + VM(uint8_t * key, uint8_t *code, uint32_t codesize); void status(void); void run(); }; diff --git a/cpp/vmcomp.cpp b/cpp/vmcomp.cpp new file mode 100644 index 0000000..32e0215 --- /dev/null +++ b/cpp/vmcomp.cpp @@ -0,0 +1,38 @@ +#include "debug.h" +#include "vmcomp.h" + +VMComponent::VMComponent(void) { + name = NULL; + value = 0; +} +VMComponent::VMComponent(uint8_t * name, uint16_t value) { + this->name = name; + this->value = value; +} + +uint8_t * VMComponent::getName(void){ + return name; +} + +uint8_t VMComponent::getValue(void) { + return value; +} + +void VMComponent::setName(uint8_t * name) { + this->name = name; + return; +} + +void VMComponent::setValue(uint16_t value) { + this->value = value; + return; +} + +uint8_t VMComponent::toUint8(void) { + return (uint8_t) value; +} + +uint16_t VMComponent::toUint16(void) { + return (uint16_t) value; +} + diff --git a/cpp/vmcomp.h b/cpp/vmcomp.h new file mode 100644 index 0000000..52d937b --- /dev/null +++ b/cpp/vmcomp.h @@ -0,0 +1,19 @@ +#ifndef VMCOMP_H +#define VMCOMP_H +#include +class VMComponent { + private: + uint8_t * name; + uint16_t value; + public: + VMComponent(); + VMComponent(uint8_t * name, uint16_t value); + uint8_t * getName(void); + uint8_t getValue(void); + void setName(uint8_t * name); + void setValue(uint16_t value); + uint8_t toUint8(void); + uint16_t toUint16(void); +}; + +#endif \ No newline at end of file