1pub mod instruction;
2mod instructions_table;
3
4use bitflags::bitflags;
5use save_state::Savable;
6
7use crate::memory::InterruptType;
8use crate::GameBoyConfig;
9use instruction::{Condition, Instruction, Opcode, OperandType};
10
11pub trait CpuBusProvider {
12 fn read(&mut self, addr: u16) -> u8;
13 fn write(&mut self, addr: u16, data: u8);
14
15 fn take_next_interrupt(&mut self) -> Option<InterruptType>;
16 fn peek_next_interrupt(&mut self) -> Option<InterruptType>;
17
18 fn is_hdma_running(&mut self) -> bool;
19
20 fn enter_stop_mode(&mut self);
21 fn stopped(&self) -> bool;
22
23 fn trigger_write_oam_bug(&mut self, addr: u16);
25 fn trigger_read_write_oam_bug(&mut self, addr: u16);
28 fn read_no_oam_bug(&mut self, addr: u16) -> u8;
30}
31
32const INTERRUPTS_VECTOR: [u16; 5] = [0x40, 0x48, 0x50, 0x58, 0x60];
33
34#[derive(Copy, Clone, Debug, PartialEq)]
35pub struct CpuRegisters {
36 pub a: u8,
37 pub b: u8,
38 pub c: u8,
39 pub d: u8,
40 pub e: u8,
41 pub f: u8,
42 pub h: u8,
43 pub l: u8,
44 pub sp: u16,
45 pub pc: u16,
46}
47
48#[derive(Clone, Copy, Debug, PartialEq)]
49pub enum RunError {
50 IllegalInstruction
51}
52
53#[derive(Clone, Copy, Debug, PartialEq)]
54pub enum CpuState {
55 Normal,
56 InfiniteLoop,
57 Halting,
58 RunningHDMA,
59 Stopped,
60 RunningInterrupt(InterruptType),
61 Breakpoint(CpuRegisters),
62}
63
64bitflags! {
65 #[derive(Default, Savable)]
66 #[savable(bitflags)]
67 struct CpuFlags: u8 {
68 const Z = 1 << 7;
69 const N = 1 << 6;
70 const H = 1 << 5;
71 const C = 1 << 4;
72 }
73}
74
75#[derive(Default, Savable, PartialEq)]
76enum HaltMode {
77 #[default]
78 NotHalting,
79 HaltRunInterrupt,
80 HaltNoRunInterrupt,
81 HaltBug,
82}
83
84#[derive(Default, Savable)]
85pub struct Cpu {
86 pub reg_a: u8,
87 pub reg_b: u8,
88 pub reg_c: u8,
89 pub reg_d: u8,
90 pub reg_e: u8,
91 pub reg_h: u8,
92 pub reg_l: u8,
93 reg_f: CpuFlags,
94
95 pub reg_sp: u16,
96
97 pub reg_pc: u16,
98
99 enable_interrupt_next: bool,
100 ime: bool,
101 halt_mode: HaltMode,
102
103 config: GameBoyConfig,
104}
105
106impl Cpu {
107 pub fn new(config: GameBoyConfig) -> Self {
108 Self {
109 reg_a: 0,
110 reg_b: 0,
111 reg_c: 0,
112 reg_d: 0,
113 reg_e: 0,
114 reg_h: 0,
115 reg_l: 0,
116 reg_f: CpuFlags::from_bits_truncate(0),
117 reg_sp: 0,
118 reg_pc: 0,
119
120 enable_interrupt_next: false,
121 ime: false,
122 halt_mode: HaltMode::NotHalting,
123
124 config,
125 }
126 }
127
128 pub fn new_without_boot_rom(config: GameBoyConfig, is_cart_cgb: bool) -> Self {
131 let mut cpu = Self::new(config);
132
133 if cpu.config.is_dmg {
134 cpu.reg_af_write(0x01B0);
136 cpu.reg_bc_write(0x0013);
137 cpu.reg_de_write(0x00D8);
138 cpu.reg_hl_write(0x014D);
139 } else {
140 cpu.reg_af_write(0x1180);
143 cpu.reg_bc_write(0x0000);
144 if is_cart_cgb {
145 cpu.reg_de_write(0xFF56);
146 cpu.reg_hl_write(0x000D);
147 } else {
148 cpu.reg_de_write(0x0008);
150 cpu.reg_hl_write(0x007C);
151 }
152 }
153 cpu.reg_sp = 0xFFFE;
154 cpu.reg_pc = 0x0100;
155
156 cpu
157 }
158
159 pub fn next_instruction<P: CpuBusProvider>(&mut self, bus: &mut P) -> Result<CpuState, RunError> {
160 if bus.stopped() {
161 self.advance_bus(bus);
162 return Ok(CpuState::Stopped);
163 }
164
165 if bus.is_hdma_running() {
166 self.advance_bus(bus);
167 return Ok(CpuState::RunningHDMA);
168 }
169
170 if self.halt_mode == HaltMode::HaltRunInterrupt
171 || self.halt_mode == HaltMode::HaltNoRunInterrupt
172 {
173 self.advance_bus(bus);
174
175 if bus.peek_next_interrupt().is_some() {
176 self.halt_mode = HaltMode::NotHalting;
177
178 if !self.config.is_dmg {
179 self.advance_bus(bus);
180 }
181 } else {
182 return Ok(CpuState::Halting);
183 }
184 }
185
186 if self.ime && bus.peek_next_interrupt().is_some() {
187 let mut cpu_state = CpuState::Normal;
188
189 let pc = self.reg_pc;
190
191 bus.trigger_write_oam_bug(self.reg_sp);
194 self.reg_sp = self.reg_sp.wrapping_sub(1);
195 bus.write(self.reg_sp, (pc >> 8) as u8);
196
197 if let Some(int_type) = bus.take_next_interrupt() {
198 cpu_state = CpuState::RunningInterrupt(int_type);
199 self.reg_pc = INTERRUPTS_VECTOR[int_type as usize];
200 } else {
201 self.reg_pc = 0;
203 }
204
205 self.ime = false;
206
207 self.reg_sp = self.reg_sp.wrapping_sub(1);
209 bus.write(self.reg_sp, pc as u8);
210
211 self.advance_bus(bus);
213 self.advance_bus(bus);
214 self.advance_bus(bus);
215 return Ok(cpu_state);
216 }
217
218 if self.enable_interrupt_next {
219 self.ime = true;
220 self.enable_interrupt_next = false;
221 }
222
223 let pc = self.reg_pc;
224 let mut instruction = Instruction::from_byte(self.fetch_next_pc(bus), pc);
225
226 if self.halt_mode == HaltMode::HaltBug {
227 self.halt_mode = HaltMode::NotHalting;
228 self.reg_pc = pc;
230 }
231
232 if instruction.opcode == Opcode::Prefix {
233 instruction = Instruction::from_prefix(self.fetch_next_pc(bus), pc);
234 }
235
236 match self.exec_instruction(instruction, bus) {
237 Err(e) => {
238 self.reg_pc = pc;
240 Err(e)
241 }
242 Ok(r) => Ok(r)
243 }
244 }
245}
246
247impl Cpu {
248 #[inline]
249 fn reg_af_read(&self) -> u16 {
250 (self.reg_a as u16) << 8 | self.reg_f.bits() as u16
251 }
252
253 #[inline]
254 fn reg_bc_read(&self) -> u16 {
255 (self.reg_b as u16) << 8 | self.reg_c as u16
256 }
257
258 #[inline]
259 fn reg_de_read(&self) -> u16 {
260 (self.reg_d as u16) << 8 | self.reg_e as u16
261 }
262
263 #[inline]
264 fn reg_hl_read(&self) -> u16 {
265 (self.reg_h as u16) << 8 | self.reg_l as u16
266 }
267
268 #[inline]
269 fn reg_af_write(&mut self, data: u16) {
270 self.reg_a = (data >> 8) as u8;
271 self.reg_f = CpuFlags::from_bits_truncate(data as u8);
272 }
273
274 #[inline]
275 fn reg_bc_write(&mut self, data: u16) {
276 self.reg_b = (data >> 8) as u8;
277 self.reg_c = data as u8;
278 }
279
280 #[inline]
281 fn reg_de_write(&mut self, data: u16) {
282 self.reg_d = (data >> 8) as u8;
283 self.reg_e = data as u8;
284 }
285
286 #[inline]
287 fn reg_hl_write(&mut self, data: u16) {
288 self.reg_h = (data >> 8) as u8;
289 self.reg_l = data as u8;
290 }
291
292 #[inline]
293 fn flag_get(&self, flag: CpuFlags) -> bool {
294 self.reg_f.intersects(flag)
295 }
296
297 #[inline]
298 fn flag_set(&mut self, flag: CpuFlags, value: bool) {
299 self.reg_f.set(flag, value);
300 }
301
302 fn registers(&self) -> CpuRegisters {
303 CpuRegisters {
304 a: self.reg_a,
305 b: self.reg_b,
306 c: self.reg_c,
307 d: self.reg_d,
308 e: self.reg_e,
309 f: self.reg_f.bits(),
310 h: self.reg_h,
311 l: self.reg_l,
312 sp: self.reg_sp,
313 pc: self.reg_pc,
314 }
315 }
316
317 fn fetch_next_pc<P: CpuBusProvider>(&mut self, bus: &mut P) -> u8 {
318 let result = bus.read(self.reg_pc);
319 bus.trigger_read_write_oam_bug(self.reg_pc);
320 self.reg_pc = self.reg_pc.wrapping_add(1);
321 result
322 }
323
324 fn read_operand<P: CpuBusProvider>(&mut self, ty: OperandType, bus: &mut P) -> u16 {
325 match ty {
326 OperandType::RegA => self.reg_a as u16,
327 OperandType::RegB => self.reg_b as u16,
328 OperandType::RegC => self.reg_c as u16,
329 OperandType::RegD => self.reg_d as u16,
330 OperandType::RegE => self.reg_e as u16,
331 OperandType::RegH => self.reg_h as u16,
332 OperandType::RegL => self.reg_l as u16,
333 OperandType::AddrHL => bus.read(self.reg_hl_read()) as u16,
334 OperandType::AddrHLDec => {
335 let hl = self.reg_hl_read();
336 let result = bus.read(hl) as u16;
337 bus.trigger_read_write_oam_bug(hl);
338 self.reg_hl_write(hl.wrapping_sub(1));
339 result
340 }
341 OperandType::AddrHLInc => {
342 let hl = self.reg_hl_read();
343 let result = bus.read(hl) as u16;
344 bus.trigger_read_write_oam_bug(hl);
345 self.reg_hl_write(hl.wrapping_add(1));
346 result
347 }
348 OperandType::AddrBC => bus.read(self.reg_bc_read()) as u16,
349 OperandType::AddrDE => bus.read(self.reg_de_read()) as u16,
350 OperandType::RegAF => self.reg_af_read(),
351 OperandType::RegBC => self.reg_bc_read(),
352 OperandType::RegDE => self.reg_de_read(),
353 OperandType::RegHL => self.reg_hl_read(),
354 OperandType::RegSP => self.reg_sp,
355 OperandType::Imm8 => self.fetch_next_pc(bus) as u16,
356 OperandType::Imm8Signed => self.fetch_next_pc(bus) as i8 as i16 as u16,
357 OperandType::Imm16 => {
358 (self.fetch_next_pc(bus) as u16) | ((self.fetch_next_pc(bus) as u16) << 8)
359 }
360 OperandType::HighAddr8 => {
361 let addr = 0xFF00 | self.fetch_next_pc(bus) as u16;
362 bus.read(addr) as u16
363 }
364 OperandType::HighAddrC => bus.read(0xFF00 | self.reg_c as u16) as u16,
365 OperandType::Addr16 => {
366 let addr =
367 (self.fetch_next_pc(bus) as u16) | ((self.fetch_next_pc(bus) as u16) << 8);
368 bus.read(addr) as u16
369 }
370 OperandType::Implied => 0,
371 OperandType::Addr16Val16 => unreachable!(),
372 }
373 }
374
375 fn write_operand<P: CpuBusProvider>(&mut self, ty: OperandType, data: u16, bus: &mut P) {
376 match ty {
377 OperandType::RegA => self.reg_a = data as u8,
378 OperandType::RegB => self.reg_b = data as u8,
379 OperandType::RegC => self.reg_c = data as u8,
380 OperandType::RegD => self.reg_d = data as u8,
381 OperandType::RegE => self.reg_e = data as u8,
382 OperandType::RegH => self.reg_h = data as u8,
383 OperandType::RegL => self.reg_l = data as u8,
384 OperandType::AddrHL => bus.write(self.reg_hl_read(), data as u8),
385 OperandType::AddrHLDec => {
386 let hl = self.reg_hl_read();
387 bus.write(hl, data as u8);
388 self.reg_hl_write(hl.wrapping_sub(1));
389 }
390 OperandType::AddrHLInc => {
391 let hl = self.reg_hl_read();
392 bus.write(hl, data as u8);
393 self.reg_hl_write(hl.wrapping_add(1));
394 }
395 OperandType::AddrBC => bus.write(self.reg_bc_read(), data as u8),
396 OperandType::AddrDE => bus.write(self.reg_de_read(), data as u8),
397 OperandType::RegAF => self.reg_af_write(data),
398 OperandType::RegBC => self.reg_bc_write(data),
399 OperandType::RegDE => self.reg_de_write(data),
400 OperandType::RegHL => self.reg_hl_write(data),
401 OperandType::RegSP => self.reg_sp = data,
402 OperandType::HighAddr8 => {
403 let addr = 0xFF00 | self.fetch_next_pc(bus) as u16;
404 bus.write(addr, data as u8);
405 }
406 OperandType::HighAddrC => bus.write(0xFF00 | self.reg_c as u16, data as u8),
407 OperandType::Addr16 => {
408 let addr =
409 (self.fetch_next_pc(bus) as u16) | ((self.fetch_next_pc(bus) as u16) << 8);
410 bus.write(addr, data as u8);
411 }
412 OperandType::Addr16Val16 => {
413 let addr =
414 (self.fetch_next_pc(bus) as u16) | ((self.fetch_next_pc(bus) as u16) << 8);
415 bus.write(addr, data as u8);
416 bus.write(addr.wrapping_add(1), (data >> 8) as u8);
417 }
418 OperandType::Implied => {}
419 OperandType::Imm16 | OperandType::Imm8 | OperandType::Imm8Signed => unreachable!(),
420 }
421 }
422
423 fn advance_bus<P: CpuBusProvider>(&mut self, bus: &mut P) {
425 bus.read(0);
426 }
427
428 pub fn stack_push<P: CpuBusProvider>(&mut self, data: u16, bus: &mut P) {
429 bus.trigger_write_oam_bug(self.reg_sp);
430 self.reg_sp = self.reg_sp.wrapping_sub(1);
431 bus.write(self.reg_sp, (data >> 8) as u8);
432 self.reg_sp = self.reg_sp.wrapping_sub(1);
433 bus.write(self.reg_sp, data as u8);
434 }
435
436 pub fn stack_pop<P: CpuBusProvider>(&mut self, bus: &mut P) -> u16 {
437 let low = bus.read_no_oam_bug(self.reg_sp);
438 bus.trigger_read_write_oam_bug(self.reg_sp);
443
444 self.reg_sp = self.reg_sp.wrapping_add(1);
445 let high = bus.read(self.reg_sp);
446 self.reg_sp = self.reg_sp.wrapping_add(1);
447
448 ((high as u16) << 8) | low as u16
449 }
450
451 fn check_cond(&self, cond: Condition) -> bool {
452 match cond {
453 Condition::NC => !self.flag_get(CpuFlags::C),
454 Condition::C => self.flag_get(CpuFlags::C),
455 Condition::NZ => !self.flag_get(CpuFlags::Z),
456 Condition::Z => self.flag_get(CpuFlags::Z),
457 Condition::Unconditional => true,
458 }
459 }
460
461 fn exec_instruction<P: CpuBusProvider>(
462 &mut self,
463 instruction: Instruction,
464 bus: &mut P,
465 ) -> Result<CpuState, RunError> {
466 let src = self.read_operand(instruction.src, bus);
467
468 let mut cpu_state = CpuState::Normal;
469
470 let result = match instruction.opcode {
471 Opcode::Nop => Ok(0),
472 Opcode::Ld => Ok(src),
473 Opcode::LdBB => {
474 println!("Break point at {:04X} was hit", instruction.pc);
476
477 cpu_state = CpuState::Breakpoint(self.registers());
478
479 Ok(0)
480 }
481 Opcode::LdSPHL => {
482 self.advance_bus(bus);
483 self.reg_sp = self.reg_hl_read();
484 Ok(0)
485 }
486 Opcode::LdHLSPSigned8 => {
487 self.advance_bus(bus);
488 let result = self.reg_sp.wrapping_add(src);
489
490 self.flag_set(CpuFlags::Z, false);
491 self.flag_set(CpuFlags::N, false);
492 self.flag_set(CpuFlags::H, (self.reg_sp & 0xf) + (src & 0xf) > 0xf);
493 self.flag_set(CpuFlags::C, (self.reg_sp & 0xff) + (src & 0xff) > 0xff);
494
495 Ok(result)
496 }
497 Opcode::Push => {
498 self.advance_bus(bus);
499 self.stack_push(src, bus);
500 Ok(0)
501 }
502 Opcode::Pop => Ok(self.stack_pop(bus)),
503 Opcode::Inc16 => {
504 self.advance_bus(bus);
505 bus.trigger_write_oam_bug(src);
506 Ok(src.wrapping_add(1))
507 }
508
509 Opcode::Inc => {
510 let result = src.wrapping_add(1) & 0xff;
511
512 self.flag_set(CpuFlags::Z, result == 0);
513 self.flag_set(CpuFlags::N, false);
514 self.flag_set(CpuFlags::H, result & 0x0f == 0);
515
516 Ok(result)
517 }
518 Opcode::Dec16 => {
519 self.advance_bus(bus);
520 bus.trigger_write_oam_bug(src);
521 Ok(src.wrapping_sub(1))
522 }
523 Opcode::Dec => {
524 let result = src.wrapping_sub(1);
525 self.flag_set(CpuFlags::Z, result == 0);
526 self.flag_set(CpuFlags::N, true);
527 self.flag_set(CpuFlags::H, result & 0x0f == 0x0f);
528 Ok(result)
529 }
530 Opcode::Add => {
531 let dest = self.read_operand(instruction.dest, bus);
532 let result = dest.wrapping_add(src);
533
534 self.flag_set(CpuFlags::Z, result & 0xFF == 0);
535 self.flag_set(CpuFlags::N, false);
536 self.flag_set(CpuFlags::H, (dest & 0xf) + (src & 0xf) > 0xf);
537 self.flag_set(CpuFlags::C, result & 0xff00 != 0);
538
539 Ok(result & 0xFF)
540 }
541 Opcode::Add16 => {
542 self.advance_bus(bus);
543 let dest = self.read_operand(instruction.dest, bus);
544 let result = (dest as u32).wrapping_add(src as u32);
545
546 self.flag_set(CpuFlags::N, false);
547 self.flag_set(CpuFlags::H, (dest & 0xfff) + (src & 0xfff) > 0xfff);
548 self.flag_set(CpuFlags::C, result & 0xffff0000 != 0);
549
550 Ok(result as u16)
551 }
552 Opcode::AddSPSigned8 => {
553 self.advance_bus(bus);
554 self.advance_bus(bus);
555 let dest = self.read_operand(instruction.dest, bus);
556 let result = dest.wrapping_add(src);
557
558 self.flag_set(CpuFlags::Z, false);
559 self.flag_set(CpuFlags::N, false);
560 self.flag_set(CpuFlags::H, (dest & 0xf) + (src & 0xf) > 0xf);
561 self.flag_set(CpuFlags::C, (dest & 0xff) + (src & 0xff) > 0xff);
562
563 Ok(result)
564 }
565 Opcode::Adc => {
566 let dest = self.read_operand(instruction.dest, bus);
567 let carry = self.flag_get(CpuFlags::C) as u16;
568 let result = dest.wrapping_add(src).wrapping_add(carry);
569
570 self.flag_set(CpuFlags::Z, result & 0xFF == 0);
571 self.flag_set(CpuFlags::N, false);
572 self.flag_set(CpuFlags::H, (dest & 0xf) + (src & 0xf) + carry > 0xf);
573 self.flag_set(CpuFlags::C, result & 0xff00 != 0);
574
575 Ok(result)
576 }
577 Opcode::Sub => {
578 let dest = self.read_operand(instruction.dest, bus);
579 let result = dest.wrapping_sub(src);
580
581 self.flag_set(CpuFlags::Z, result & 0xFF == 0);
582 self.flag_set(CpuFlags::N, true);
583 self.flag_set(CpuFlags::H, (dest & 0xf) < (src & 0xf));
584 self.flag_set(CpuFlags::C, result & 0xff00 != 0);
585
586 Ok(result & 0xFF)
587 }
588 Opcode::Cp => {
589 let dest = self.reg_a as u16;
590 let result = dest.wrapping_sub(src);
591
592 self.flag_set(CpuFlags::Z, result & 0xFF == 0);
593 self.flag_set(CpuFlags::N, true);
594 self.flag_set(CpuFlags::H, (dest & 0xf) < (src & 0xf));
595 self.flag_set(CpuFlags::C, result & 0xff00 != 0);
596
597 Ok(result & 0xFF)
599 }
600 Opcode::Sbc => {
601 let dest = self.read_operand(instruction.dest, bus);
602 let carry = self.flag_get(CpuFlags::C) as u16;
603 let result = dest.wrapping_sub(src).wrapping_sub(carry);
604
605 self.flag_set(CpuFlags::Z, result & 0xFF == 0);
606 self.flag_set(CpuFlags::N, true);
607 self.flag_set(
608 CpuFlags::H,
609 (dest & 0xf).wrapping_sub(src & 0xf).wrapping_sub(carry) > 0xf,
610 );
611 self.flag_set(CpuFlags::C, result & 0xff00 != 0);
612
613 Ok(result & 0xFF)
614 }
615 Opcode::And => {
616 let dest = self.read_operand(instruction.dest, bus);
617 let result = dest & src & 0xff;
618
619 self.flag_set(CpuFlags::Z, result == 0);
620 self.flag_set(CpuFlags::N, false);
621 self.flag_set(CpuFlags::H, true);
622 self.flag_set(CpuFlags::C, false);
623
624 Ok(result)
625 }
626 Opcode::Xor => {
627 let dest = self.read_operand(instruction.dest, bus);
628 let result = (dest ^ src) & 0xff;
629
630 self.flag_set(CpuFlags::Z, result == 0);
631 self.flag_set(CpuFlags::N, false);
632 self.flag_set(CpuFlags::H, false);
633 self.flag_set(CpuFlags::C, false);
634
635 Ok(result)
636 }
637 Opcode::Or => {
638 let dest = self.read_operand(instruction.dest, bus);
639 let result = (dest | src) & 0xff;
640
641 self.flag_set(CpuFlags::Z, result == 0);
642 self.flag_set(CpuFlags::N, false);
643 self.flag_set(CpuFlags::H, false);
644 self.flag_set(CpuFlags::C, false);
645
646 Ok(result)
647 }
648 Opcode::Jp(cond) => {
649 if self.check_cond(cond) {
650 self.advance_bus(bus);
651 if cond == Condition::Unconditional && src == instruction.pc {
652 cpu_state = CpuState::InfiniteLoop;
653 }
654
655 self.reg_pc = src;
656 }
657 Ok(0)
658 }
659 Opcode::JpHL => {
660 if src == instruction.pc {
661 cpu_state = CpuState::InfiniteLoop;
662 }
663
664 self.reg_pc = src;
665 Ok(0)
666 }
667 Opcode::Jr(cond) => {
668 if self.check_cond(cond) {
669 self.advance_bus(bus);
670 let new_pc = self.reg_pc.wrapping_add(src);
671
672 if cond == Condition::Unconditional && new_pc == instruction.pc {
673 cpu_state = CpuState::InfiniteLoop;
674 }
675
676 self.reg_pc = new_pc;
677 }
678 Ok(0)
679 }
680 Opcode::Call(cond) => {
681 if self.check_cond(cond) {
682 self.advance_bus(bus);
683 self.stack_push(self.reg_pc, bus);
684 self.reg_pc = src;
685 }
686 Ok(0)
687 }
688 Opcode::Ret(cond) => {
689 if cond != Condition::Unconditional {
690 self.advance_bus(bus);
691 }
692 if self.check_cond(cond) {
693 self.reg_pc = self.stack_pop(bus);
694 self.advance_bus(bus);
695 }
696 Ok(0)
697 }
698 Opcode::Reti => {
699 self.reg_pc = self.stack_pop(bus);
700 self.advance_bus(bus);
701 self.ime = true;
702 Ok(0)
703 }
704 Opcode::Rst(loc) => {
705 self.advance_bus(bus);
706 self.stack_push(self.reg_pc, bus);
707 self.reg_pc = loc as u16;
708 Ok(0)
709 }
710 Opcode::Di => {
711 self.ime = false;
712 Ok(0)
713 }
714 Opcode::Ei => {
715 self.enable_interrupt_next = true;
716 Ok(0)
717 }
718 Opcode::Ccf => {
719 self.flag_set(CpuFlags::N, false);
720 self.flag_set(CpuFlags::H, false);
721 self.flag_set(CpuFlags::C, !self.flag_get(CpuFlags::C));
722 Ok(0)
723 }
724 Opcode::Scf => {
725 self.flag_set(CpuFlags::N, false);
726 self.flag_set(CpuFlags::H, false);
727 self.flag_set(CpuFlags::C, true);
728 Ok(0)
729 }
730 Opcode::Daa => {
731 let carry = self.flag_get(CpuFlags::C);
732 let halfcarry = self.flag_get(CpuFlags::H);
733
734 if !self.flag_get(CpuFlags::N) {
735 let mut correction = 0;
736 if halfcarry || (self.reg_a & 0xf > 0x9) {
737 correction |= 0x6;
738 }
739
740 if carry || (self.reg_a > 0x99) {
741 correction |= 0x60;
742 self.flag_set(CpuFlags::C, true);
743 }
744
745 self.reg_a = self.reg_a.wrapping_add(correction);
746 } else if carry {
747 self.flag_set(CpuFlags::C, true);
748 self.reg_a = self.reg_a.wrapping_add(if halfcarry { 0x9a } else { 0xa0 });
749 } else if halfcarry {
750 self.reg_a = self.reg_a.wrapping_add(0xfa);
751 }
752
753 self.flag_set(CpuFlags::Z, self.reg_a == 0);
754 self.flag_set(CpuFlags::H, false);
755
756 Ok(0)
757 }
758 Opcode::Cpl => {
759 self.reg_a = !self.reg_a;
760
761 self.flag_set(CpuFlags::N, true);
762 self.flag_set(CpuFlags::H, true);
763
764 Ok(0)
765 }
766 Opcode::Rlca => {
767 let carry = (self.reg_a >> 7) & 1;
768 self.reg_a = self.reg_a.wrapping_shl(1) | carry;
769
770 self.flag_set(CpuFlags::Z, false);
771 self.flag_set(CpuFlags::N, false);
772 self.flag_set(CpuFlags::H, false);
773 self.flag_set(CpuFlags::C, carry == 1);
774
775 Ok(0)
776 }
777 Opcode::Rla => {
778 let carry = (self.reg_a >> 7) & 1;
779 self.reg_a = self.reg_a.wrapping_shl(1) | self.flag_get(CpuFlags::C) as u8;
780
781 self.flag_set(CpuFlags::Z, false);
782 self.flag_set(CpuFlags::N, false);
783 self.flag_set(CpuFlags::H, false);
784 self.flag_set(CpuFlags::C, carry == 1);
785
786 Ok(0)
787 }
788 Opcode::Rrca => {
789 let carry = self.reg_a & 1;
790 self.reg_a = self.reg_a.wrapping_shr(1) | (carry << 7);
791
792 self.flag_set(CpuFlags::Z, false);
793 self.flag_set(CpuFlags::N, false);
794 self.flag_set(CpuFlags::H, false);
795 self.flag_set(CpuFlags::C, carry == 1);
796
797 Ok(0)
798 }
799 Opcode::Rra => {
800 let carry = self.reg_a & 1;
801 self.reg_a = self.reg_a.wrapping_shr(1) | ((self.flag_get(CpuFlags::C) as u8) << 7);
802
803 self.flag_set(CpuFlags::Z, false);
804 self.flag_set(CpuFlags::N, false);
805 self.flag_set(CpuFlags::H, false);
806 self.flag_set(CpuFlags::C, carry == 1);
807
808 Ok(0)
809 }
810 Opcode::Rlc => {
811 let carry = (src >> 7) & 1;
812 let result = src.wrapping_shl(1) | carry & 0xFF;
813
814 self.flag_set(CpuFlags::Z, result == 0);
815 self.flag_set(CpuFlags::N, false);
816 self.flag_set(CpuFlags::H, false);
817 self.flag_set(CpuFlags::C, carry == 1);
818
819 Ok(result)
820 }
821 Opcode::Rrc => {
822 let carry = src & 1;
823 let result = src.wrapping_shr(1) | (carry << 7) & 0xFF;
824
825 self.flag_set(CpuFlags::Z, result == 0);
826 self.flag_set(CpuFlags::N, false);
827 self.flag_set(CpuFlags::H, false);
828 self.flag_set(CpuFlags::C, carry == 1);
829
830 Ok(result)
831 }
832 Opcode::Rl => {
833 let carry = (src >> 7) & 1;
834 let result = (src.wrapping_shl(1) | self.flag_get(CpuFlags::C) as u16) & 0xFF;
835
836 self.flag_set(CpuFlags::Z, result == 0);
837 self.flag_set(CpuFlags::N, false);
838 self.flag_set(CpuFlags::H, false);
839 self.flag_set(CpuFlags::C, carry == 1);
840
841 Ok(result)
842 }
843 Opcode::Rr => {
844 let carry = src & 1;
845 let result =
846 (src.wrapping_shr(1) | ((self.flag_get(CpuFlags::C) as u16) << 7)) & 0xFF;
847
848 self.flag_set(CpuFlags::Z, result == 0);
849 self.flag_set(CpuFlags::N, false);
850 self.flag_set(CpuFlags::H, false);
851 self.flag_set(CpuFlags::C, carry == 1);
852
853 Ok(result)
854 }
855 Opcode::Sla => {
856 let carry = (src >> 7) & 1;
857 let result = src.wrapping_shl(1) & 0xFF;
858
859 self.flag_set(CpuFlags::Z, result == 0);
860 self.flag_set(CpuFlags::N, false);
861 self.flag_set(CpuFlags::H, false);
862 self.flag_set(CpuFlags::C, carry == 1);
863
864 Ok(result)
865 }
866 Opcode::Sra => {
867 let carry = src & 1;
868 let result = (src.wrapping_shr(1) | (src & 0x80)) & 0xFF;
869
870 self.flag_set(CpuFlags::Z, result == 0);
871 self.flag_set(CpuFlags::N, false);
872 self.flag_set(CpuFlags::H, false);
873 self.flag_set(CpuFlags::C, carry == 1);
874
875 Ok(result)
876 }
877 Opcode::Swap => {
878 let result = ((src >> 4) & 0xf) | ((src & 0xf) << 4);
879
880 self.flag_set(CpuFlags::Z, result == 0);
881 self.flag_set(CpuFlags::N, false);
882 self.flag_set(CpuFlags::H, false);
883 self.flag_set(CpuFlags::C, false);
884
885 Ok(result)
886 }
887 Opcode::Srl => {
888 let carry = src & 1;
889 let result = src.wrapping_shr(1) & 0xFF;
890
891 self.flag_set(CpuFlags::Z, result == 0);
892 self.flag_set(CpuFlags::N, false);
893 self.flag_set(CpuFlags::H, false);
894 self.flag_set(CpuFlags::C, carry == 1);
895
896 Ok(result)
897 }
898 Opcode::Bit(bit) => {
899 self.flag_set(CpuFlags::Z, (src >> bit) & 1 == 0);
900 self.flag_set(CpuFlags::N, false);
901 self.flag_set(CpuFlags::H, true);
902 Ok(0)
903 }
904 Opcode::Res(bit) => Ok(src & !((1 << bit) as u16)),
905 Opcode::Set(bit) => Ok(src | ((1 << bit) as u16)),
906 Opcode::Halt => {
907 self.halt_mode = if self.ime {
925 HaltMode::HaltRunInterrupt
926 } else if bus.peek_next_interrupt().is_some() {
927 HaltMode::HaltBug
928 } else {
929 HaltMode::HaltNoRunInterrupt
930 };
931
932 Ok(0)
933 }
934 Opcode::Stop => {
935 bus.enter_stop_mode();
937 Ok(0)
938 }
939 Opcode::Illegal => Err(RunError::IllegalInstruction),
940 Opcode::Prefix => unreachable!(),
941 }?;
942
943 self.write_operand(instruction.dest, result, bus);
950
951 Ok(cpu_state)
952 }
953}