简体   繁体   中英

How do I write a macro that conditionally updates an emulators CPU flags?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM