Because both AAM and AAD are two-byte instructions, hardcoding the second "operand" as 10 meant that the second byte was never accounted for. Additionally, real Intel 8086 CPUs had an undocumented behavior that was not implemented in EXACT: the second byte in AAM and AAD (which was normally 0x0A
) was actually the "operand" and could be something other than 10, too.
By reading the next code byte and stepping through the instruction pointer once, we can replicate the undocumented behavior and also fix the emulator's own length mismatch bug.
I also noticed that this "reading over byte/word and stepping the IP register" functionality was repeated quite often across the codebase, so I placed them under the $fetch_byte
and $fetch_word
boilerplate functions, reducing redundancy in lots of cases.