I'm writing a 6502 CPU emulator using Rust and I'm trying to make my code as DRY as possible.
The code for decoding opcodes and executing them looks like this:
//self refers to CPU struct
match opcode {
0x29 => {self.A &= self.imm(); update_flags!(self.cpu, "Z0", "N7");},
// ... other 55 opcodes
}
I want an easy way to update the CPU flags after executing each instruction. For example, after executing the AND instruction, flag Z should be set if A = 0 and flag N should be set if bit 7 is 1. I could describe these two conditions as Z0 and N7.
I need to write a macro that takes the CPU struct, Z0 and N7 as arguments and expands into something like:
if self.A == 0 {set flag Z};
if self.A.7thbit == 1 {set flag N};
Is this possible?
A macro is not necessary here, since equal (if not better) ergonomy and efficiency can be achieved with functions.
For example, you could define methods such as:
fn Z(&mut self, value: u8) {
self.z_flag = self.A == value;
}
fn N(&mut self, bit: u8) {
self.n_flag = self.A & (1u8 << bit) != 0;
}
Instead of update_flags!(self.cpu, "Z0", "N7");
, you would write self.Z(0); self.N(7);
self.Z(0); self.N(7);
. When called with constant args, they should be as efficient as the macros would have been.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.