1use std::{
2 fmt::Display,
3 ops::{AddAssign, Not},
4};
5
6#[derive(PartialEq, Eq, Clone, Copy, Debug)]
7pub enum Register {
8 A(u8),
9 APair(u8, u8),
10 B(u8),
11 BPair(u8, u8),
12}
13
14impl Register {
15 pub fn from(value: u8, side: bool) -> Self {
16 if side == false {
17 Self::A(value)
18 } else {
19 Self::B(value)
20 }
21 }
22
23 pub fn from_pair(value: u8, side: bool) -> Self {
24 let value2 = value - value % 2;
25 let value1 = value2 + 1;
26 if side == false {
27 Self::APair(value1, value2)
28 } else {
29 Self::BPair(value1, value2)
30 }
31 }
32
33 pub fn side(&self) -> bool {
34 match self {
35 Self::A(_) => false,
36 Self::APair(_, _) => false,
37 Self::B(_) => true,
38 Self::BPair(_, _) => true,
39 }
40 }
41}
42
43impl Display for Register {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 match self {
46 Self::A(num) => write!(f, "A{num}"),
47 Self::APair(num1, num2) => write!(f, "A{num1}:A{num2}"),
48 Self::B(num) => write!(f, "B{num}"),
49 Self::BPair(num1, num2) => write!(f, "B{num1}:B{num2}"),
50 }
51 }
52}
53
54impl AddAssign<u8> for Register {
55 fn add_assign(&mut self, rhs: u8) {
56 match self {
57 Self::A(num) | Self::B(num) => *num += rhs,
58 Self::APair(num1, num2) | Self::BPair(num1, num2) => {
59 *num1 += rhs - rhs % 2;
60 *num2 = *num1 - 1;
61 }
62 }
63 }
64}
65
66impl Not for Register {
67 type Output = Self;
68
69 fn not(self) -> Self::Output {
70 match self {
71 Self::A(num) => Self::B(num),
72 Self::APair(num1, num2) => Self::BPair(num1, num2),
73 Self::B(num) => Self::A(num),
74 Self::BPair(num1, num2) => Self::APair(num1, num2),
75 }
76 }
77}
78
79#[derive(PartialEq, Eq, Clone, Copy, Debug)]
80pub enum ControlRegister {
81 AMR,
83 CSR,
85 GFPGFR,
87 ICR,
89 IER,
91 IFR,
93 IRP,
95 ISR,
97 ISTP,
99 NRP,
101 PCE1,
103
104 DIER,
107 DNUM,
109 ECR,
111 EFR,
113 GPLYA,
115 GPLYB,
117 IERR,
119 ILC,
121 ITSR,
123 NTSR,
125 REP,
127 RILC,
129 SSR,
131 TSCH,
133 TSCL,
135 TSR,
137}
138
139impl ControlRegister {
140 pub fn from(low: u8, high: u8) -> Option<Self> {
141 match low {
142 0b00000 => Some(Self::AMR),
143 0b00001 => Some(Self::CSR),
144 0b11001 => Some(Self::DIER),
145 0b10001 => Some(Self::DNUM),
146 0b11101 => Some(Self::ECR),
147 0b11000 => Some(Self::GFPGFR),
148 0b10110 => Some(Self::GPLYA),
149 0b10111 => Some(Self::GPLYB),
150 0b00011 => Some(Self::ICR),
151 0b00100 => Some(Self::IER),
152 0b11111 => Some(Self::IERR),
153 0b00010 if high == 0b00000 || high == 0b00010 => Some(Self::IFR),
154 0b00010 => Some(Self::ISR),
155 0b01101 => Some(Self::ILC),
156 0b00110 => Some(Self::IRP),
157 0b00101 => Some(Self::ISTP),
158 0b11011 => Some(Self::ITSR),
159 0b00111 => Some(Self::NRP),
160 0b11100 => Some(Self::NTSR),
161 0b10000 => Some(Self::PCE1),
162 0b01111 => Some(Self::REP),
163 0b01110 => Some(Self::RILC),
164 0b10101 => Some(Self::SSR),
165 0b01011 => Some(Self::TSCH),
166 0b01010 => Some(Self::TSCL),
167 0b11010 => Some(Self::TSR),
168 _ => None,
169 }
170 }
171}
172
173impl Display for ControlRegister {
174 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175 match self {
176 Self::AMR => write!(f, "AMR"),
177 Self::CSR => write!(f, "CSR"),
178 Self::GFPGFR => write!(f, "GFPGFR"),
179 Self::ICR => write!(f, "ICR"),
180 Self::IER => write!(f, "IER"),
181 Self::IFR => write!(f, "IFR"),
182 Self::IRP => write!(f, "IRP"),
183 Self::ISR => write!(f, "ISR"),
184 Self::ISTP => write!(f, "ISTP"),
185 Self::NRP => write!(f, "NRP"),
186 Self::PCE1 => write!(f, "PCE1"),
187 Self::DIER => write!(f, "DIER"),
188 Self::DNUM => write!(f, "DNUM"),
189 Self::ECR => write!(f, "ECR"),
190 Self::EFR => write!(f, "EFR"),
191 Self::GPLYA => write!(f, "GPLYA"),
192 Self::GPLYB => write!(f, "GPLYB"),
193 Self::IERR => write!(f, "IERR"),
194 Self::ILC => write!(f, "ILC"),
195 Self::ITSR => write!(f, "ITSR"),
196 Self::NTSR => write!(f, "NTSR"),
197 Self::REP => write!(f, "REP"),
198 Self::RILC => write!(f, "RILC"),
199 Self::SSR => write!(f, "SSR"),
200 Self::TSCH => write!(f, "TSCH"),
201 Self::TSCL => write!(f, "TSCL"),
202 Self::TSR => write!(f, "TSR"),
203 }
204 }
205}
206
207pub enum RegisterFile {
208 GeneralPurpose(Register),
209 Control(ControlRegister),
210}
211
212impl RegisterFile {
213 pub fn side(&self) -> Option<bool> {
214 if let Self::GeneralPurpose(register) = self {
215 Some(register.side())
216 } else {
217 None
218 }
219 }
220}
221
222impl Display for RegisterFile {
223 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 match self {
225 Self::GeneralPurpose(register) => write!(f, "{register}"),
226 Self::Control(register) => write!(f, "{register}"),
227 }
228 }
229}