#include <stdio.h> #include <inttypes.h> typedef enum { A = 0, B, C, D } Registers; typedef enum { FLAG_ZERO = 1, FLAG_NEGATIVE = 1 << 1, } Flags; typedef enum { OP_ADD, OP_ADD_VALUE, OP_HALT, OP_JMP_REL, OP_JMP_REL_NEGATIVE, OP_JMP_REL_NOT_EQUAL, OP_JMP_REL_EQUAL, OP_LOAD, OP_MOV, OP_XCHG, OP_NOP, OP_PRINT, OP_TEST, } OpCode; static void set_flags(int16_t value, uint8_t *flags_register) { int new_flags = 0; if (value == 0) new_flags |= FLAG_ZERO; if (value < 0) new_flags |= FLAG_NEGATIVE; *flags_register = new_flags; } int main() { int16_t program[] = { OP_LOAD, A, 255, OP_LOAD, B, 0, OP_ADD, B, A, OP_ADD_VALUE, A, -1, OP_TEST, A, 0, OP_JMP_REL_NOT_EQUAL, -11, OP_PRINT, B, OP_HALT }; int16_t registers[4] = { 0 }; uint8_t flags_register = 0; uint16_t *ip = (uint16_t *) program; while (1) { OpCode op = *ip++; switch (op) { case OP_LOAD: { int16_t idx = *ip++; registers[idx] = *ip++; set_flags(registers[idx], &flags_register); break; } case OP_ADD: { int16_t idx = *ip++; int16_t val = registers[*ip++]; registers[idx] += val; set_flags(registers[idx], &flags_register); break; } case OP_ADD_VALUE: { /* TODO */ break; } case OP_JMP_REL: { /* TODO */ break; } case OP_NOP: { break; } case OP_TEST: { /* TODO */ break; } case OP_JMP_REL_NOT_EQUAL: { /* TODO */ break; } case OP_JMP_REL_NEGATIVE: { /* TODO */ break; } case OP_JMP_REL_EQUAL: { /* TODO */ break; } case OP_MOV: { /* TODO */ break; } case OP_XCHG: { /* TODO */ break; } case OP_PRINT: printf("%d\n", registers[*ip++]); break; case OP_HALT: return 0; default: fprintf(stderr, "Unknown instruction %" PRId16 "\n", *ip); return -1; } } return 0; }