use super::{Cpu, low_byte, wide_value};
use crate::mcode::{Decoded, IndexState, InstructionSet};
impl Cpu {
pub(super) fn immediate_address(&self) -> u16 {
wide_value(self.data_latch, low_byte(self.tmp_addr))
}
pub(super) fn set_latch(&mut self, value: u16) {
self.registers.wz = value;
}
pub(super) fn set_latch_from_accumulator(&mut self, address: u16) {
let low = low_byte(address.wrapping_add(1));
self.registers.wz = wide_value(self.accumulator(), low);
}
#[allow(clippy::too_many_lines)]
pub(super) fn update_latch(&mut self, decoded: &Decoded, cycle: u8) {
if !matches!(self.index_state, IndexState::None) && self.index_displaced() {
self.registers.wz = self.tmp_addr;
}
match self.instruction_set {
InstructionSet::Cb => {}
InstructionSet::Ed => self.update_latch_extended(decoded, cycle),
_ => self.update_latch_base(decoded, cycle),
}
}
pub(super) fn update_latch_base(&mut self, decoded: &Decoded, cycle: u8) {
let ir = self.ir;
let indexed = !matches!(self.index_state, IndexState::None);
match ir {
0x0A if cycle == 1 => self.set_latch(self.registers.bc.wrapping_add(1)),
0x1A if cycle == 1 => self.set_latch(self.registers.de.wrapping_add(1)),
0x02 if cycle == 1 => self.set_latch_from_accumulator(self.registers.bc),
0x12 if cycle == 1 => self.set_latch_from_accumulator(self.registers.de),
0x3A if cycle == 3 => self.set_latch(self.immediate_address().wrapping_add(1)),
0x32 if cycle == 3 => self.set_latch_from_accumulator(self.immediate_address()),
0x2A | 0x22 if cycle == 3 => self.set_latch(self.tmp_addr.wrapping_add(1)),
0x09 | 0x19 | 0x29 | 0x39 if cycle == 1 => {
let base = if indexed {
self.wide(self.index_register())
} else {
self.registers.hl
};
self.set_latch(base.wrapping_add(1));
}
0xC3 | 0xC2 | 0xCA | 0xD2 | 0xDA | 0xE2 | 0xEA | 0xF2 | 0xFA | 0xC9 | 0xC0 | 0xC8
| 0xD0 | 0xD8 | 0xE0 | 0xE8 | 0xF0 | 0xF8
if cycle == 3 =>
{
self.set_latch(self.immediate_address());
}
0xCD | 0xC4 | 0xCC | 0xD4 | 0xDC | 0xE4 | 0xEC | 0xF4 | 0xFC | 0xC7 | 0xCF | 0xD7
| 0xDF | 0xE7 | 0xEF | 0xF7 | 0xFF
if cycle == 3 =>
{
self.set_latch(self.tmp_addr);
}
0x18 | 0x20 | 0x28 | 0x30 | 0x38 | 0x10 if cycle == 3 && decoded.jump_e() => {
self.set_latch(self.registers.pc);
}
0xDB if cycle == 2 => self.set_latch(self.address.wrapping_add(1)),
0xD3 if cycle == 2 => self.set_latch_from_accumulator(self.address),
0xE3 if cycle == 5 => self.set_latch(self.tmp_addr),
_ => {}
}
}
pub(super) fn update_latch_extended(&mut self, decoded: &Decoded, cycle: u8) {
let ir = self.ir;
let _ = decoded;
match ir {
0x4B | 0x5B | 0x6B | 0x7B | 0x43 | 0x53 | 0x63 | 0x73 if cycle == 3 => {
self.set_latch(self.tmp_addr.wrapping_add(1));
}
0x4A | 0x5A | 0x6A | 0x7A | 0x42 | 0x52 | 0x62 | 0x72 if cycle == 1 => {
self.set_latch(self.registers.hl.wrapping_add(1));
}
0x40 | 0x48 | 0x50 | 0x58 | 0x60 | 0x68 | 0x70 | 0x78 | 0x41 | 0x49 | 0x51 | 0x59
| 0x61 | 0x69 | 0x71 | 0x79
if cycle == 1 =>
{
self.set_latch(self.registers.bc.wrapping_add(1));
}
0x4D | 0x45 | 0x55 | 0x5D | 0x65 | 0x6D | 0x75 | 0x7D if cycle == 3 => {
self.set_latch(self.immediate_address());
}
0x67 | 0x6F if cycle == 1 => self.set_latch(self.registers.hl.wrapping_add(1)),
0xA1 | 0xA9 | 0xB1 | 0xB9 if cycle == 1 => {
let stepped = if ir & 0x08 == 0 {
self.registers.wz.wrapping_add(1)
} else {
self.registers.wz.wrapping_sub(1)
};
self.set_latch(stepped);
}
0xA2 | 0xAA | 0xB2 | 0xBA if cycle == 1 => {
let stepped = if ir & 0x08 == 0 {
self.registers.bc.wrapping_add(1)
} else {
self.registers.bc.wrapping_sub(1)
};
self.set_latch(stepped);
}
0xA3 | 0xAB | 0xB3 | 0xBB if cycle == 3 => {
let stepped = if ir & 0x08 == 0 {
self.registers.bc.wrapping_add(1)
} else {
self.registers.bc.wrapping_sub(1)
};
self.set_latch(stepped);
}
0xB0 | 0xB8 | 0xB1 | 0xB9 if cycle == 4 => {
self.set_latch(self.registers.pc.wrapping_add(1));
}
_ => {}
}
}
}