Skip to main content

monistode_emulator/
flag_register.rs

1pub enum ProcessorFlags {
2    CF = 0b0000000000000001,
3    ZF = 0b0000000000000010,
4    OF = 0b0000000000000100,
5    SF = 0b0000000000001000,
6}
7
8pub trait FlagRegister {
9    fn set(&mut self, flag: ProcessorFlags);
10    fn get(&self, flag: ProcessorFlags) -> bool;
11    fn clear(&mut self, flag: ProcessorFlags);
12    fn is_set(&self, flag: ProcessorFlags) -> bool;
13    fn is_clear(&self, flag: ProcessorFlags) -> bool;
14    fn reset(&mut self);
15
16    #[inline]
17    fn set_if(&mut self, condition: bool, flag: ProcessorFlags) {
18        if condition {
19            self.set(flag);
20        } else {
21            self.clear(flag);
22        }
23    }
24}
25
26macro_rules! implement_flag_register {
27    ($name:ident($type:ty)) => {
28        #[derive(Debug, Clone, Copy)]
29        pub struct $name(pub $type);
30
31        impl $name {
32            fn new() -> $name {
33                $name(0)
34            }
35        }
36
37        impl FlagRegister for $name {
38            #[inline]
39            fn set(&mut self, flag: ProcessorFlags) {
40                self.0 |= flag as $type;
41            }
42
43            fn get(&self, flag: ProcessorFlags) -> bool {
44                self.0 & (flag as $type) != 0
45            }
46
47            #[inline]
48            fn clear(&mut self, flag: ProcessorFlags) {
49                self.0 &= !(flag as $type);
50            }
51
52            #[inline]
53            fn is_set(&self, flag: ProcessorFlags) -> bool {
54                self.0 & (flag as $type) != 0
55            }
56
57            #[inline]
58            fn is_clear(&self, flag: ProcessorFlags) -> bool {
59                !self.is_set(flag)
60            }
61
62            #[inline]
63            fn reset(&mut self) {
64                self.0 = 0;
65            }
66        }
67
68        impl Into<$type> for $name {
69            fn into(self) -> $type {
70                self.0
71            }
72        }
73    };
74}
75
76pub(crate) use implement_flag_register;