cpclib_tokens/tokens/
registers.rs

1use std::fmt;
2
3#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy, Hash)]
4#[allow(missing_docs)]
5pub enum Register16 {
6    Af,
7    Hl,
8    De,
9    Bc,
10    Sp
11}
12impl fmt::Display for Register16 {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        let code = match self {
15            Register16::Af => "AF",
16            Register16::Bc => "BC",
17            Register16::De => "DE",
18            Register16::Hl => "HL",
19            Register16::Sp => "SP"
20        };
21        write!(f, "{code}")
22    }
23}
24
25#[allow(missing_docs)]
26impl Register16 {
27    /// Return the high 8bit register if exists
28    pub fn high(self) -> Option<Register8> {
29        match self {
30            Register16::Af => Some(Register8::A),
31            Register16::Hl => Some(Register8::H),
32            Register16::De => Some(Register8::D),
33            Register16::Bc => Some(Register8::B),
34            Register16::Sp => None
35        }
36    }
37
38    /// Return the low 8bit register if exists
39    pub fn low(self) -> Option<Register8> {
40        match self {
41            Register16::Af | Register16::Sp => None,
42            Register16::Hl => Some(Register8::L),
43            Register16::De => Some(Register8::E),
44            Register16::Bc => Some(Register8::C)
45        }
46    }
47
48    pub fn split(self) -> (Option<Register8>, Option<Register8>) {
49        (self.low(), self.high())
50    }
51}
52
53macro_rules! is_reg16 {
54    ($($reg:ident)*) => {$(
55        paste::paste! {
56            impl Register16 {
57                /// Check if register is $reg
58                pub fn [<is_ $reg:lower>] (&self) -> bool {
59                    match self {
60                        Register16::$reg => true,
61                        _ => false
62                    }
63                }
64            }
65        }
66
67    )*
68    }
69}
70is_reg16! {Af Bc De Hl Sp}
71
72#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
73#[allow(missing_docs)]
74pub enum IndexRegister16 {
75    Ix,
76    Iy
77}
78
79impl IndexRegister16 {
80    pub fn high(self) -> IndexRegister8 {
81        match self {
82            Self::Ix => IndexRegister8::Ixh,
83            Self::Iy => IndexRegister8::Iyh
84        }
85    }
86
87    /// Return the low 8bit register if exists
88    pub fn low(self) -> IndexRegister8 {
89        match self {
90            Self::Ix => IndexRegister8::Ixl,
91            Self::Iy => IndexRegister8::Iyl
92        }
93    }
94}
95
96impl fmt::Display for IndexRegister16 {
97    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98        use self::*;
99        let code = match self {
100            IndexRegister16::Ix => "IX",
101            IndexRegister16::Iy => "IY"
102        };
103        write!(f, "{code}")
104    }
105}
106
107#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Hash, Copy)]
108#[allow(missing_docs)]
109pub enum Register8 {
110    A,
111    B,
112    C,
113    D,
114    E,
115    H,
116    L
117}
118
119#[allow(missing_docs)]
120impl Register8 {
121    pub fn is_high(self) -> bool {
122        match self {
123            Register8::A | Register8::B | Register8::D | Register8::H => true,
124            _ => false
125        }
126    }
127
128    pub fn is_low(self) -> bool {
129        !self.is_high()
130    }
131
132    pub fn neighbourg(self) -> Option<Self> {
133        match self {
134            Register8::A => None,
135            Register8::B => Some(Register8::C),
136            Register8::C => Some(Register8::B),
137            Register8::D => Some(Register8::E),
138            Register8::E => Some(Register8::D),
139            Register8::H => Some(Register8::L),
140            Register8::L => Some(Register8::H)
141        }
142    }
143
144    /// Return the 16bit register than contains this one
145    pub fn complete(self) -> Register16 {
146        match self {
147            Register8::A => Register16::Af,
148            Register8::B | Register8::C => Register16::Bc,
149            Register8::D | Register8::E => Register16::De,
150            Register8::H | Register8::L => Register16::Hl
151        }
152    }
153}
154
155macro_rules! is_reg8 {
156    ($($reg:ident)*) => {$(
157        paste::paste! {
158            impl Register8 {
159                /// Check if register is $reg
160                pub fn [<is_ $reg:lower>] (&self) -> bool {
161                    match self {
162                        Register8::$reg => true,
163                        _ => false
164                    }
165                }
166            }
167        }
168
169    )*
170    }
171}
172is_reg8! {A B C D E H L}
173
174impl fmt::Display for Register8 {
175    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176        use self::*;
177        let code = match self {
178            Register8::A => "A",
179            Register8::B => "B",
180            Register8::C => "C",
181            Register8::D => "D",
182            Register8::E => "E",
183            Register8::H => "H",
184            Register8::L => "L"
185        };
186        write!(f, "{code}")
187    }
188}
189
190#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
191#[allow(missing_docs)]
192pub enum IndexRegister8 {
193    Ixh,
194    Ixl,
195    Iyh,
196    Iyl
197}
198
199impl fmt::Display for IndexRegister8 {
200    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201        use self::*;
202        let code = match self {
203            IndexRegister8::Ixh => "IXH",
204            IndexRegister8::Ixl => "IXL",
205            IndexRegister8::Iyh => "IYH",
206            IndexRegister8::Iyl => "IYL"
207        };
208        write!(f, "{code}")
209    }
210}
211
212impl IndexRegister8 {
213    /// Return the 16 bit register composed by this 8 bits register
214    pub fn complete(&self) -> IndexRegister16 {
215        match self {
216            IndexRegister8::Ixh | IndexRegister8::Ixl => IndexRegister16::Ix,
217            IndexRegister8::Iyh | IndexRegister8::Iyl => IndexRegister16::Iy
218        }
219    }
220
221    /// Return true if it is the high register for the complete one
222    pub fn is_high(self) -> bool {
223        match self {
224            IndexRegister8::Ixh | IndexRegister8::Iyh => true,
225            _ => false
226        }
227    }
228
229    /// Return true if it is the low register for the complete one
230    pub fn is_low(self) -> bool {
231        !self.is_high()
232    }
233}
234// #[derive(Debug, PartialEq, Eq)]
235// pub struct Label;
236//
237// #[derive(Debug, PartialEq, Eq)]
238// pub enum Value{
239// Label(),
240// Constant
241// }
242
243// TODO add missing flags
244#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
245#[allow(missing_docs)]
246pub enum FlagTest {
247    NZ,
248    Z,
249    NC,
250    C,
251    PO,
252    PE,
253    P,
254    M
255}
256
257impl fmt::Display for FlagTest {
258    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259        let code = match self {
260            FlagTest::NZ => "NZ",
261            FlagTest::Z => "Z",
262            FlagTest::NC => "NC",
263            FlagTest::C => "C",
264            FlagTest::PO => "PO",
265            FlagTest::PE => "PE",
266            FlagTest::P => "P",
267            FlagTest::M => "M"
268        };
269        write!(f, "{code}")
270    }
271}