diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-23 01:43:24 +0100 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-23 01:43:24 +0100 |
commit | 2ef104f2358af14339ff632f3457bbb9dbf56d92 (patch) | |
tree | 3f57a106d7739d63d75ee8d7fdd2b98cc500eba5 /src | |
parent | 20030e364cd869e5651b2e2fb63cfb8881fbf5b7 (diff) | |
download | ovm-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/runtime.c | 12 |
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; } |