use bitflags::bitflags;
use proc_macro2::TokenStream;
use quote::quote;
use crate::compiler::args::{CrateFetcher, Literal};
use crate::compiler::instr::builder::{InstrBuilder, MicrocodeReadable, MicrocodeWritable};
use crate::microcode::Microcode;
bitflags! {
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Flags: u8 {
const ZERO = 0x80;
const SUB = 0x40;
const HALFCARRY = 0x20;
const CARRY = 0x10;
}
}
impl Flags {
pub fn merge(&mut self, flags: Flags, mask: Flags) {
*self = (*self & !mask) | (flags & mask);
}
pub fn check_zero(val: u8) -> Flags {
if val == 0 {
Flags::ZERO
} else {
Flags::empty()
}
}
pub fn check_carry(carry: bool) -> Flags {
if carry {
Flags::CARRY
} else {
Flags::empty()
}
}
}
impl MicrocodeWritable for Flags {
fn to_write(self) -> InstrBuilder {
Microcode::SetFlagsMasked { mask: self }.into()
}
}
impl MicrocodeReadable for Flags {
fn to_read(self) -> InstrBuilder {
Microcode::GetFlagsMasked { mask: self }.into()
}
}
impl Literal for Flags {
fn constant_value(&self, crates: CrateFetcher) -> TokenStream {
let feo3boy_opcodes = crates("feo3boy-opcodes");
let val = format!("0b{:b}u8", self.bits())
.parse::<proc_macro2::Literal>()
.unwrap();
quote! { #feo3boy_opcodes::gbz80types::Flags::from_bits_retain(#val) }.into()
}
}