Removed temp var. Fixed PC.

Changed PC to be 8bits and checking for alignment.
Introduced x/y vars.
This commit is contained in:
2018-10-16 22:25:27 +01:00
parent 0359d4e0b2
commit 40a1add41d
4 changed files with 51 additions and 33 deletions

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

2
main.c
View File

@@ -13,8 +13,6 @@ int main() {
}; };
memcpy(&vm->M, data, 6); memcpy(&vm->M, data, 6);
printf("%i\n", (uint8_t)0x101);
while(!vm->halted) { while(!vm->halted) {
vm_step(vm); vm_step(vm);
} }

74
vm.c
View File

@@ -80,7 +80,12 @@ void vm_step(VM *vm) {
VM_Instruction inst; VM_Instruction inst;
memset(&inst, 0, sizeof(VM_Instruction)); memset(&inst, 0, sizeof(VM_Instruction));
uint16_t PC = vm->PC; uint8_t PC = vm->PC;
if (PC % 2 != 0) {
fprintf(stderr, "Halted. PC not aligned.\n");
vm->halted = true;
return;
}
uint16_t raw = (vm->M[PC] << 8) + vm->M[PC + 1]; uint16_t raw = (vm->M[PC] << 8) + vm->M[PC + 1];
vm->PC += 2; vm->PC += 2;
inst.op = (uint8_t) (raw >> 12); inst.op = (uint8_t) (raw >> 12);
@@ -89,98 +94,107 @@ void vm_step(VM *vm) {
return; return;
} }
uint8_t temp = 0, x = 0, y = 0; uint8_t x = 0;
uint8_t y = 0;
uint8_t d = 0;
uint16_t temp16 = 0; uint16_t temp16 = 0;
switch (inst.op) { switch (inst.op) {
case OP_LDA: case OP_LDA:
vm_decode_Q(&inst, raw); vm_decode_Q(&inst, raw);
vm_put_r(vm, inst.rd, vm->M[inst.imm]); d = vm->M[inst.imm];
break; break;
case OP_STA: case OP_STA:
vm_decode_Q(&inst, raw); vm_decode_Q(&inst, raw);
vm->M[inst.imm] = (uint8_t) vm_get_r(vm, inst.rd); vm->M[inst.imm] = vm_get_r(vm, inst.rd);
break; break;
case OP_LDI: case OP_LDI:
vm_decode_Q(&inst, raw); vm_decode_Q(&inst, raw);
vm_put_r(vm, inst.rd, inst.imm); d = inst.imm;
break; break;
case OP_ADD: case OP_ADD:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
vm->carry = 0; vm->carry = 0;
temp = vm_get_r(vm, inst.rx) + vm_get_r(vm, inst.ry); x = vm_get_r(vm, inst.rx);
vm_put_r(vm, inst.rd, temp); y = vm_get_r(vm, inst.ry);
d = x + y;
break; break;
case OP_ADC: case OP_ADC:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
temp16 = vm_get_r(vm, inst.rx) + vm_get_r(vm, inst.ry) + vm->carry; x = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry);
temp16 = x + y + vm->carry;
vm->carry = (uint8_t) (temp16 >> 8); vm->carry = (uint8_t) (temp16 >> 8);
vm_put_r(vm, inst.rd, (uint8_t)temp16); d = (uint8_t) temp16;
break; break;
case OP_SUB: case OP_SUB:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
vm->carry = 0; vm->carry = 0;
temp = vm_get_r(vm, inst.rx) - vm_get_r(vm, inst.ry); x = vm_get_r(vm, inst.rx);
vm_put_r(vm, inst.rd, temp); y = vm_get_r(vm, inst.ry);
d = x - y;
break; break;
case OP_SBC: case OP_SBC:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
x = vm_get_r(vm, inst.rx); x = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry); y = vm_get_r(vm, inst.ry);
temp = vm_subtract(x, y, &vm->carry); d = vm_subtract(x, y, &vm->carry);
vm_put_r(vm, inst.rd, temp);
break; break;
case OP_NOT: case OP_NOT:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
temp = vm_get_r(vm, inst.rx); d = ~x;
vm_put_r(vm, inst.rd, ~temp);
break; break;
case OP_AND: case OP_AND:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
temp = vm_get_r(vm, inst.rx) & vm_get_r(vm, inst.ry); x = vm_get_r(vm, inst.rx);
vm_put_r(vm, inst.rd, temp); y = vm_get_r(vm, inst.ry);
d = x & y;
break; break;
case OP_SHL: case OP_SHL:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
temp = vm_get_r(vm, inst.rx) << vm_get_r(vm, (uint8_t) inst.imm); x = vm_get_r(vm, inst.rx);
vm_put_r(vm, inst.rd, temp); d = x << vm_get_r(vm, inst.imm);
break; break;
case OP_SHR: case OP_SHR:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
temp = vm_get_r(vm, inst.rx) >> vm_get_r(vm, (uint8_t) inst.imm); x = vm_get_r(vm, inst.rx);
vm_put_r(vm, inst.rd, temp); d = x >> vm_get_r(vm, inst.imm);
break; break;
case OP_SYS: case OP_SYS:
vm_decode_Q(&inst, raw); vm_decode_Q(&inst, raw);
if (vm->syscall != NULL) { if (vm->syscall != NULL) {
temp = vm->syscall(vm, inst.imm); d = vm->syscall(vm, inst.imm);
vm_put_r(vm, inst.rd, temp);
} else { } else {
printf("SYSCALL #%d\n", inst.imm); printf("SYSCALL #%d\n", inst.imm);
} }
break; break;
case OP_JMP: case OP_JMP:
vm_decode_Q(&inst, raw); vm_decode_Q(&inst, raw);
vm->PC = vm->M[inst.rd]; vm->PC = vm_get_r(vm, inst.rd);
break; break;
case OP_JEQ: case OP_JEQ:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
if (vm_get_r(vm, inst.rx) == vm_get_r(vm, inst.ry)) { x = vm_get_r(vm, inst.rx);
vm->PC = vm->M[inst.rd]; y = vm_get_r(vm, inst.ry);
if (x == y) {
vm->PC = vm_get_r(vm, inst.rd);
} }
break; break;
case OP_JLT: case OP_JLT:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
if (vm_get_r(vm, inst.rx) < vm_get_r(vm, inst.ry)) { x = vm_get_r(vm, inst.rx);
vm->PC = vm->M[inst.rd]; y = vm_get_r(vm, inst.ry);
if (x < y) {
vm->PC = vm_get_r(vm, inst.rd);
} }
break; break;
case OP_HLT: case OP_HLT:
printf("Halted at 0x%04hX\n", PC); printf("Halted at 0x%04X\n", PC);
vm->halted = true; vm->halted = true;
break; break;
default: default:
printf("Unknown Instruction at 0x%04hX: 0x%hhX\n", PC, inst.op); printf("Unknown Instruction at 0x%04X: 0x%hhX\n", PC, inst.op);
vm->halted = true; vm->halted = true;
break; break;
} }
vm_put_r(vm, inst.rd, d);
} }

2
vm.h
View File

@@ -39,7 +39,7 @@ typedef struct VM_Instruction_t VM_Instruction;
struct VM_t { struct VM_t {
uint8_t R[VM_REG_SIZE]; uint8_t R[VM_REG_SIZE];
uint16_t PC; uint8_t PC;
uint8_t M[VM_MEM_SIZE]; uint8_t M[VM_MEM_SIZE];
uint8_t carry; uint8_t carry;
bool halted; bool halted;