diff options
author | Juan J. Martinez <jjm@usebox.net> | 2023-05-23 16:06:46 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2023-05-23 16:08:48 +0100 |
commit | c5dd4897e4d7f45108b6955bebf2d4b5f22a3652 (patch) | |
tree | a85d5b933fe2dccf57dd476194a27b0f5d99becd /vm.c | |
parent | 5584f79fff0fdfc8e4430eea3867c729b82f4152 (diff) | |
download | tr8vm-c5dd4897e4d7f45108b6955bebf2d4b5f22a3652.tar.gz tr8vm-c5dd4897e4d7f45108b6955bebf2d4b5f22a3652.zip |
Add cmpi, cmpd, ldi and ldd
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 79 |
1 files changed, 78 insertions, 1 deletions
@@ -453,13 +453,90 @@ uint8_t tr8_eval(Tr8 *vm) } break; + case 14: + if (FHL(instr)) + { + if (FHH(instr)) + { + uint8_t f = 0; + + /* CMPI */ + flags(&vm->f, vm->read_m(ADDR(vm->regs[0], vm->regs[2])) - vm->read_m(ADDR(vm->regs[1], vm->regs[3])), ZF | CF | OF | SF); + + vm->regs[2] = flags(&f, vm->regs[2] + 1, OF); + if (f & OF) + vm->regs[0]++; + + vm->regs[3] = flags(&f, vm->regs[3] + 1, OF); + if (f & OF) + vm->regs[1]++; + + vm->icnt += 3; + } + else + { + uint8_t f = 0; + + /* CMPD */ + flags(&vm->f, vm->read_m(ADDR(vm->regs[0], vm->regs[2])) - vm->read_m(ADDR(vm->regs[1], vm->regs[3])), ZF | CF | OF | SF); + + vm->regs[2] = flags(&f, vm->regs[2] - 1, OF); + if (f & OF) + vm->regs[0]--; + + vm->regs[3] = flags(&f, vm->regs[3] - 1, OF); + if (f & OF) + vm->regs[1]--; + + vm->icnt += 3; + } + } + else + { + if (FHH(instr)) + { + uint8_t f = 0; + + /* LDI */ + vm->write_m(ADDR(vm->regs[1], vm->regs[3]), vm->read_m(ADDR(vm->regs[0], vm->regs[2]))); + + vm->regs[2] = flags(&f, vm->regs[2] + 1, OF); + if (f & OF) + vm->regs[0]++; + + vm->regs[3] = flags(&f, vm->regs[3] + 1, OF); + if (f & OF) + vm->regs[1]++; + + vm->icnt += 3; + } + else + { + uint8_t f = 0; + + /* LDD */ + vm->write_m(ADDR(vm->regs[1], vm->regs[3]), vm->read_m(ADDR(vm->regs[0], vm->regs[2]))); + + vm->regs[2] = flags(&f, vm->regs[2] - 1, OF); + if (f & OF) + vm->regs[0]--; + + vm->regs[3] = flags(&f, vm->regs[3] - 1, OF); + if (f & OF) + vm->regs[1]--; + + vm->icnt += 3; + } + } + break; + default: fprintf(stderr, "*invalid opcode 0x%01x at PC=0x%04x*\n", (instr >> 12), 2 * (vm->pc - 1)); tr8_dump(vm, stderr); return 1; } - if (vm->icnt == INSTR_PER_FRAME) + if (vm->icnt >= INSTR_PER_FRAME) return 1; } } |