Newer
Older
} 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,
set_flags(int16_t value, uint8_t *flags_register)
new_flags |= FLAG_NEGATIVE;
*flags_register = new_flags;
int16_t program[] = {
OP_LOAD, A, 255,
OP_ADD, B, A,
OP_ADD_VALUE, A, -1,
OP_TEST, A, 0,
OP_JMP_REL_NOT_EQUAL, -11,
OP_PRINT, B,
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: {
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_JMP_REL_NOT_EQUAL: {
break;
}
case OP_JMP_REL_NEGATIVE: {
/* TODO */
break;
}
case OP_JMP_REL_EQUAL: {
/* TODO */
break;
}
case OP_PRINT:
printf("%d\n", registers[*ip++]);
break;
case OP_HALT:
return 0;
default:
fprintf(stderr, "Unknown instruction %" PRId16 "\n", *ip);