1use crate::bus::Bus;
16use crate::registers::Registers;
17
18mod opcodes;
19
20pub const VEC_RESET: u16 = 0xFFFE;
25pub const VEC_NMI: u16 = 0xFFFC;
26pub const VEC_SWI: u16 = 0xFFFA;
27pub const VEC_IRQ: u16 = 0xFFF8;
28pub const VEC_FIRQ: u16 = 0xFFF6;
29pub const VEC_SWI2: u16 = 0xFFF4;
30pub const VEC_SWI3: u16 = 0xFFF2;
31
32pub struct Cpu {
38 pub reg: Registers,
40 pub cycles: u64,
42 pub halted: bool,
44 pub illegal: bool,
46
47 nmi_armed: bool,
50 nmi_pending: bool,
52 firq_line: bool,
54 irq_line: bool,
56 cwai: bool,
58 sync: bool,
60}
61
62impl Cpu {
63 pub fn new() -> Self {
65 Self {
66 reg: Registers::new(),
67 cycles: 0,
68 halted: false,
69 illegal: false,
70 nmi_armed: false,
71 nmi_pending: false,
72 firq_line: false,
73 irq_line: false,
74 cwai: false,
75 sync: false,
76 }
77 }
78
79 pub fn reset(&mut self, bus: &mut impl Bus) {
81 self.reg = Registers::new();
82 self.reg.cc.set_irq_inhibit(true);
83 self.reg.cc.set_firq_inhibit(true);
84 self.reg.pc = bus.read_word(VEC_RESET);
85 self.cycles = 0;
86 self.halted = false;
87 self.illegal = false;
88 self.nmi_armed = false;
89 self.nmi_pending = false;
90 self.firq_line = false;
91 self.irq_line = false;
92 self.cwai = false;
93 self.sync = false;
94 }
95
96 pub fn set_irq(&mut self, active: bool) {
98 self.irq_line = active;
99 }
100
101 pub fn set_firq(&mut self, active: bool) {
103 self.firq_line = active;
104 }
105
106 pub fn trigger_nmi(&mut self) {
108 if self.nmi_armed {
109 self.nmi_pending = true;
110 }
111 }
112
113 pub fn step(&mut self, bus: &mut impl Bus) -> u64 {
116 if self.halted {
117 return 1;
118 }
119
120 let start_cycles = self.cycles;
121
122 if self.sync {
124 if self.nmi_pending || self.firq_line || self.irq_line {
125 self.sync = false;
126 } else {
127 self.cycles += 1;
128 return 1;
129 }
130 }
131
132 if self.check_interrupts(bus) {
134 return self.cycles - start_cycles;
135 }
136
137 let opcode = self.fetch_byte(bus);
139 self.execute(bus, opcode);
140
141 self.cycles - start_cycles
142 }
143
144 pub fn run(&mut self, bus: &mut impl Bus, cycle_budget: u64) -> u64 {
146 let start_cycles = self.cycles;
147 let target = self.cycles + cycle_budget;
148 while self.cycles < target && !self.halted {
149 self.step(bus);
150 }
151 self.cycles - start_cycles
152 }
153
154 fn check_interrupts(&mut self, bus: &mut impl Bus) -> bool {
157 if self.nmi_pending {
159 self.nmi_pending = false;
160 if !self.cwai {
161 self.reg.cc.set_entire(true);
162 self.push_entire_state(bus);
163 }
164 self.cwai = false;
165 self.reg.cc.set_irq_inhibit(true);
166 self.reg.cc.set_firq_inhibit(true);
167 self.reg.pc = bus.read_word(VEC_NMI);
168 self.cycles += 19;
169 return true;
170 }
171
172 if self.firq_line && !self.reg.cc.firq_inhibit() {
174 if !self.cwai {
175 self.reg.cc.set_entire(false);
176 self.push_word_s(bus, self.reg.pc);
177 self.push_byte_s(bus, self.reg.cc.to_byte());
178 }
179 self.cwai = false;
180 self.reg.cc.set_irq_inhibit(true);
181 self.reg.cc.set_firq_inhibit(true);
182 self.reg.pc = bus.read_word(VEC_FIRQ);
183 self.cycles += 10;
184 return true;
185 }
186
187 if self.irq_line && !self.reg.cc.irq_inhibit() {
189 if !self.cwai {
190 self.reg.cc.set_entire(true);
191 self.push_entire_state(bus);
192 }
193 self.cwai = false;
194 self.reg.cc.set_irq_inhibit(true);
195 self.reg.pc = bus.read_word(VEC_IRQ);
196 self.cycles += 19;
197 return true;
198 }
199
200 false
201 }
202
203 pub(super) fn push_byte_s(&mut self, bus: &mut impl Bus, val: u8) {
207 self.reg.s = self.reg.s.wrapping_sub(1);
208 bus.write(self.reg.s, val);
209 }
210
211 pub(super) fn push_word_s(&mut self, bus: &mut impl Bus, val: u16) {
213 self.push_byte_s(bus, val as u8); self.push_byte_s(bus, (val >> 8) as u8);
215 }
216
217 pub(super) fn pull_byte_s(&mut self, bus: &mut impl Bus) -> u8 {
219 let val = bus.read(self.reg.s);
220 self.reg.s = self.reg.s.wrapping_add(1);
221 val
222 }
223
224 pub(super) fn pull_word_s(&mut self, bus: &mut impl Bus) -> u16 {
226 let hi = self.pull_byte_s(bus) as u16;
227 let lo = self.pull_byte_s(bus) as u16;
228 (hi << 8) | lo
229 }
230
231 pub(super) fn push_byte_u(&mut self, bus: &mut impl Bus, val: u8) {
233 self.reg.u = self.reg.u.wrapping_sub(1);
234 bus.write(self.reg.u, val);
235 }
236
237 pub(super) fn push_word_u(&mut self, bus: &mut impl Bus, val: u16) {
239 self.push_byte_u(bus, val as u8);
240 self.push_byte_u(bus, (val >> 8) as u8);
241 }
242
243 pub(super) fn pull_byte_u(&mut self, bus: &mut impl Bus) -> u8 {
245 let val = bus.read(self.reg.u);
246 self.reg.u = self.reg.u.wrapping_add(1);
247 val
248 }
249
250 pub(super) fn pull_word_u(&mut self, bus: &mut impl Bus) -> u16 {
252 let hi = self.pull_byte_u(bus) as u16;
253 let lo = self.pull_byte_u(bus) as u16;
254 (hi << 8) | lo
255 }
256
257 pub(super) fn push_entire_state(&mut self, bus: &mut impl Bus) {
260 self.push_word_s(bus, self.reg.pc);
261 self.push_word_s(bus, self.reg.u);
262 self.push_word_s(bus, self.reg.y);
263 self.push_word_s(bus, self.reg.x);
264 self.push_byte_s(bus, self.reg.dp);
265 self.push_byte_s(bus, self.reg.b());
266 self.push_byte_s(bus, self.reg.a());
267 self.push_byte_s(bus, self.reg.cc.to_byte());
268 }
269
270 pub(super) fn fetch_byte(&mut self, bus: &mut impl Bus) -> u8 {
274 let val = bus.read(self.reg.pc);
275 self.reg.pc = self.reg.pc.wrapping_add(1);
276 val
277 }
278
279 pub(super) fn fetch_word(&mut self, bus: &mut impl Bus) -> u16 {
281 let hi = self.fetch_byte(bus) as u16;
282 let lo = self.fetch_byte(bus) as u16;
283 (hi << 8) | lo
284 }
285
286 pub(super) fn addr_direct(&mut self, bus: &mut impl Bus) -> u16 {
290 let lo = self.fetch_byte(bus) as u16;
291 ((self.reg.dp as u16) << 8) | lo
292 }
293
294 pub(super) fn addr_extended(&mut self, bus: &mut impl Bus) -> u16 {
296 self.fetch_word(bus)
297 }
298
299 pub(super) fn addr_indexed(&mut self, bus: &mut impl Bus) -> (u16, u8) {
301 crate::addressing::indexed(self, bus)
302 }
303
304 pub(super) fn addr_relative8(&mut self, bus: &mut impl Bus) -> u16 {
306 let offset = self.fetch_byte(bus) as i8 as i16 as u16;
307 self.reg.pc.wrapping_add(offset)
308 }
309
310 pub(super) fn addr_relative16(&mut self, bus: &mut impl Bus) -> u16 {
312 let offset = self.fetch_word(bus);
313 self.reg.pc.wrapping_add(offset)
314 }
315
316 pub(super) fn arm_nmi(&mut self) {
318 self.nmi_armed = true;
319 }
320}
321
322impl Default for Cpu {
323 fn default() -> Self {
324 Self::new()
325 }
326}
327
328impl fmt::Debug for Cpu {
329 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
330 write!(f, "{} cyc={}", self.reg, self.cycles)
331 }
332}
333
334use std::fmt;