1use crate::core::instructions::{ 2 BlockMode, InstructionExecutor, parity_flag, sign_flag, zero_flag, 3}; 4use crate::core::{Flags, Register16}; 5use crate::debug::BusDebugExt; 6use crate::traits::BusInterface; 7 8impl<B: BusInterface> InstructionExecutor<'_, '_, B> { 9 pub(super) fn in_a_n(&mut self) -> u32 { 10 let operand = self.fetch_operand(); 11 let io_address = u16::from_be_bytes([self.cpu.registers.a, operand]); 12 13 self.cpu.registers.a = self.bus.read_io_debug(io_address, self.cpu); 14 15 11 16 } 17 18 pub(super) fn in_r_c(&mut self, opcode: u8) -> u32 { 19 let register = super::parse_register_from_opcode(opcode >> 3, None); 20 let io_address = u16::from_be_bytes([self.cpu.registers.b, self.cpu.registers.c]); 21 let value = self.bus.read_io_debug(io_address, self.cpu); 22 23 if let Some(register) = register { 24 register.write_to(value, &mut self.cpu.registers); 25 } 26 27 self.cpu.registers.f = Flags { 28 sign: sign_flag(value), 29 zero: zero_flag(value), 30 half_carry: false, 31 overflow: parity_flag(value), 32 subtract: false, 33 ..self.cpu.registers.f 34 }; 35 36 12 37 } 38 39 pub(super) fn in_block(&mut self, mode: BlockMode, repeat: bool) -> u32 { 40 let b = self.cpu.registers.b; 41 let io_address = u16::from_be_bytes([b, self.cpu.registers.c]); 42 let value = self.bus.read_io_debug(io_address, self.cpu); 43 44 let hl = Register16::HL.read_from(&self.cpu.registers); 45 self.bus.write_memory_debug(hl, value, self.cpu); 46 47 self.cpu.registers.b = b.wrapping_sub(1); 48 49 Register16::HL.write_to(mode.apply(hl), &mut self.cpu.registers); 50 51 let should_repeat = repeat && b != 1; 52 if should_repeat { 53 self.cpu.registers.pc -= 2; 54 } 55 56 self.cpu.registers.f = 57 Flags { zero: repeat || b == 1, subtract: true, ..self.cpu.registers.f }; 58 59 if should_repeat { 21 } else { 16 } 60 } 61 62 pub(super) fn out_n_a(&mut self) -> u32 { 63 let operand = self.fetch_operand(); 64 let io_address = u16::from_be_bytes([self.cpu.registers.a, operand]); 65 66 self.bus.write_io_debug(io_address, self.cpu.registers.a, self.cpu); 67 68 11 69 } 70 71 pub(super) fn out_c_r(&mut self, opcode: u8) -> u32 { 72 let register = super::parse_register_from_opcode(opcode >> 3, None); 73 let io_address = u16::from_be_bytes([self.cpu.registers.b, self.cpu.registers.c]); 74 let value = match register { 75 Some(register) => register.read_from(&self.cpu.registers), 76 None => 0, 77 }; 78 79 self.bus.write_io_debug(io_address, value, self.cpu); 80 81 12 82 } 83 84 pub(super) fn out_block(&mut self, mode: BlockMode, repeat: bool) -> u32 { 85 let hl = Register16::HL.read_from(&self.cpu.registers); 86 let value = self.bus.read_memory_debug(hl, self.cpu); 87 88 let b = self.cpu.registers.b; 89 self.cpu.registers.b = b.wrapping_sub(1); 90 91 let io_address = u16::from_be_bytes([self.cpu.registers.b, self.cpu.registers.c]); 92 self.bus.write_io_debug(io_address, value, self.cpu); 93 94 Register16::HL.write_to(mode.apply(hl), &mut self.cpu.registers); 95 96 let should_repeat = repeat && b != 1; 97 if should_repeat { 98 self.cpu.registers.pc -= 2; 99 } 100 101 self.cpu.registers.f = 102 Flags { zero: repeat || b == 1, subtract: true, ..self.cpu.registers.f }; 103 104 if should_repeat { 21 } else { 16 } 105 } 106}