feo3boy_opcodes/microcode/
args.rs

1//! Types which are used as arguments to the [`Microcode`][crate::microcode::Microcode].
2use proc_macro2::{Ident, Span, TokenStream};
3use quote::quote;
4
5use crate::compiler::args::{CrateFetcher, Literal};
6use crate::compiler::instr::builder::{InstrBuilder, MicrocodeReadable, MicrocodeWritable};
7use crate::microcode::Microcode;
8
9/// Identifies an 8 bit register in the microcode.
10#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
11pub enum Reg8 {
12    Acc,
13    B,
14    C,
15    D,
16    E,
17    H,
18    L,
19}
20
21impl MicrocodeReadable for Reg8 {
22    fn to_read(self) -> InstrBuilder {
23        Microcode::ReadReg { reg: self }.into()
24    }
25}
26
27impl MicrocodeWritable for Reg8 {
28    fn to_write(self) -> InstrBuilder {
29        Microcode::WriteReg { reg: self }.into()
30    }
31}
32
33impl Literal for Reg8 {
34    fn constant_value(&self, crates: CrateFetcher) -> TokenStream {
35        let feo3boy_opcodes = crates("feo3boy-opcodes");
36        let val = match self {
37            Self::Acc => "Acc",
38            Self::B => "B",
39            Self::C => "C",
40            Self::D => "D",
41            Self::E => "E",
42            Self::H => "H",
43            Self::L => "L",
44        };
45        let val = Ident::new(val, Span::call_site());
46        quote! { #feo3boy_opcodes::microcode::args::Reg8::#val }
47    }
48}
49
50/// Identifies a 16 bit register in the microcode.
51#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
52pub enum Reg16 {
53    AF,
54    BC,
55    DE,
56    HL,
57    Sp,
58    Pc,
59}
60
61impl MicrocodeReadable for Reg16 {
62    fn to_read(self) -> InstrBuilder {
63        Microcode::ReadReg16 { reg: self }.into()
64    }
65}
66
67impl MicrocodeWritable for Reg16 {
68    fn to_write(self) -> InstrBuilder {
69        Microcode::WriteReg16 { reg: self }.into()
70    }
71}
72
73impl Literal for Reg16 {
74    fn constant_value(&self, crates: CrateFetcher) -> TokenStream {
75        let feo3boy_opcodes = crates("feo3boy-opcodes");
76        let val = match self {
77            Self::AF => "AF",
78            Self::BC => "BC",
79            Self::DE => "DE",
80            Self::HL => "HL",
81            Self::Sp => "Sp",
82            Self::Pc => "Pc",
83        };
84        let val = Ident::new(val, Span::call_site());
85        quote! { #feo3boy_opcodes::microcode::args::Reg16::#val }.into()
86    }
87}