1use std::fmt;
16
17pub(crate) const CC_C: u8 = 0x01; pub(crate) const CC_V: u8 = 0x02; pub(crate) const CC_Z: u8 = 0x04; pub(crate) const CC_N: u8 = 0x08; pub(crate) const CC_I: u8 = 0x10; pub(crate) const CC_H: u8 = 0x20; pub(crate) const CC_F: u8 = 0x40; pub(crate) const CC_E: u8 = 0x80; #[repr(transparent)]
37#[derive(Clone, Copy, Default, PartialEq, Eq)]
38pub struct ConditionCodes(u8);
39impl ConditionCodes {
40 pub const fn new() -> Self {
41 Self(0)
42 }
43
44 pub const fn from_byte(b: u8) -> Self {
45 Self(b)
46 }
47
48 pub const fn to_byte(self) -> u8 {
49 self.0
50 }
51
52 pub const fn carry(self) -> bool {
55 self.0 & CC_C != 0
56 }
57 pub const fn overflow(self) -> bool {
58 self.0 & CC_V != 0
59 }
60 pub const fn zero(self) -> bool {
61 self.0 & CC_Z != 0
62 }
63 pub const fn negative(self) -> bool {
64 self.0 & CC_N != 0
65 }
66 pub const fn irq_inhibit(self) -> bool {
67 self.0 & CC_I != 0
68 }
69 pub const fn half_carry(self) -> bool {
70 self.0 & CC_H != 0
71 }
72 pub const fn firq_inhibit(self) -> bool {
73 self.0 & CC_F != 0
74 }
75 pub const fn entire(self) -> bool {
76 self.0 & CC_E != 0
77 }
78
79 pub fn set_carry(&mut self, v: bool) {
82 self.set_bit(CC_C, v);
83 }
84 pub fn set_overflow(&mut self, v: bool) {
85 self.set_bit(CC_V, v);
86 }
87 pub fn set_zero(&mut self, v: bool) {
88 self.set_bit(CC_Z, v);
89 }
90 pub fn set_negative(&mut self, v: bool) {
91 self.set_bit(CC_N, v);
92 }
93 pub fn set_irq_inhibit(&mut self, v: bool) {
94 self.set_bit(CC_I, v);
95 }
96 pub fn set_half_carry(&mut self, v: bool) {
97 self.set_bit(CC_H, v);
98 }
99 pub fn set_firq_inhibit(&mut self, v: bool) {
100 self.set_bit(CC_F, v);
101 }
102 pub fn set_entire(&mut self, v: bool) {
103 self.set_bit(CC_E, v);
104 }
105
106 pub fn set_nz8(&mut self, val: u8) {
108 self.set_negative(val & 0x80 != 0);
109 self.set_zero(val == 0);
110 }
111
112 pub fn set_nz16(&mut self, val: u16) {
114 self.set_negative(val & 0x8000 != 0);
115 self.set_zero(val == 0);
116 }
117
118 pub fn or_with(&mut self, mask: u8) {
120 self.0 |= mask;
121 }
122
123 pub fn and_with(&mut self, mask: u8) {
125 self.0 &= mask;
126 }
127
128 fn set_bit(&mut self, mask: u8, v: bool) {
129 if v {
130 self.0 |= mask;
131 } else {
132 self.0 &= !mask;
133 }
134 }
135}
136
137impl fmt::Debug for ConditionCodes {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 write!(
140 f,
141 "CC({:02X} {}{}{}{}{}{}{}{})",
142 self.0,
143 if self.entire() { 'E' } else { '.' },
144 if self.firq_inhibit() { 'F' } else { '.' },
145 if self.half_carry() { 'H' } else { '.' },
146 if self.irq_inhibit() { 'I' } else { '.' },
147 if self.negative() { 'N' } else { '.' },
148 if self.zero() { 'Z' } else { '.' },
149 if self.overflow() { 'V' } else { '.' },
150 if self.carry() { 'C' } else { '.' },
151 )
152 }
153}
154
155impl fmt::Display for ConditionCodes {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 fmt::Debug::fmt(self, f)
158 }
159}
160
161#[repr(C)]
174#[derive(Clone, Copy, Debug, Default)]
175pub struct Registers {
176 pub d: u16,
178 pub x: u16,
180 pub y: u16,
182 pub u: u16,
184 pub s: u16,
186 pub pc: u16,
188 pub dp: u8,
190 pub cc: ConditionCodes,
192}
193
194impl Registers {
195 pub const fn new() -> Self {
196 Self {
197 d: 0,
198 x: 0,
199 y: 0,
200 u: 0,
201 s: 0,
202 pc: 0,
203 dp: 0,
204 cc: ConditionCodes::new(),
205 }
206 }
207
208 pub const fn a(self) -> u8 {
212 (self.d >> 8) as u8
213 }
214
215 pub const fn b(self) -> u8 {
217 self.d as u8
218 }
219
220 pub fn set_a(&mut self, val: u8) {
222 self.d = (self.d & 0x00FF) | ((val as u16) << 8);
223 }
224
225 pub fn set_b(&mut self, val: u8) {
227 self.d = (self.d & 0xFF00) | (val as u16);
228 }
229}
230
231impl fmt::Display for Registers {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 write!(
234 f,
235 "PC={:04X} A={:02X} B={:02X} X={:04X} Y={:04X} U={:04X} S={:04X} DP={:02X} {}",
236 self.pc,
237 self.a(),
238 self.b(),
239 self.x,
240 self.y,
241 self.u,
242 self.s,
243 self.dp,
244 self.cc,
245 )
246 }
247}