aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2023-10-23 01:43:24 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2023-10-23 01:43:24 +0100
commit2ef104f2358af14339ff632f3457bbb9dbf56d92 (patch)
tree3f57a106d7739d63d75ee8d7fdd2b98cc500eba5
parent20030e364cd869e5651b2e2fb63cfb8881fbf5b7 (diff)
downloadovm-2ef104f2358af14339ff632f3457bbb9dbf56d92.tar.gz
ovm-2ef104f2358af14339ff632f3457bbb9dbf56d92.tar.bz2
ovm-2ef104f2358af14339ff632f3457bbb9dbf56d92.zip
Fixed bug in vm_mov(byte|hword) where registers aren't set properly
This is because we just OR the bits into the specific byte of the word. This means the previous state may leave artefacts as the OR doesn't clear the bits away. To do so, we apply a bit mask to clear the specified byte(s) of the word, then perform the OR.
-rw-r--r--src/runtime.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/runtime.c b/src/runtime.c
index 2d3f1e8..1108b25 100644
--- a/src/runtime.c
+++ b/src/runtime.c
@@ -443,7 +443,11 @@ err_t vm_mov_byte(vm_t *vm, byte reg)
if (err)
return err;
word *reg_ptr = &vm->registers.reg[reg / 8];
- *reg_ptr = (*reg_ptr) | (ret.as_word << ((reg % 8) * 8));
+ size_t shift = (reg % 8) * 8;
+ // This resets the bits in the specific byte register
+ *reg_ptr = *reg_ptr & ~(0xFF << shift);
+ // This sets the bits
+ *reg_ptr = (*reg_ptr) | (ret.as_word << shift);
return ERR_OK;
}
@@ -458,7 +462,11 @@ err_t vm_mov_hword(vm_t *vm, byte reg)
if (err)
return err;
word *reg_ptr = &vm->registers.reg[reg / 2];
- *reg_ptr = (*reg_ptr) | (ret.as_word << ((reg % 2) * 2));
+ size_t shift = (reg % 2) * 2;
+ // This resets the bits in the specific hword register
+ *reg_ptr = *reg_ptr & ~(0xFFFFFFFF << shift);
+ // This sets the bits
+ *reg_ptr = (*reg_ptr) | (ret.as_word << shift);
return ERR_OK;
}