Skip to content

Commit

Permalink
daa reworked, RL A RLA etc are different instructions, dec halfcarry
Browse files Browse the repository at this point in the history
  • Loading branch information
LaurinZ committed Jun 3, 2024
1 parent 65f4e52 commit 72411db
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 37 deletions.
8 changes: 4 additions & 4 deletions src/cpu/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl CPU {
InstParam::Register8Bit(Register8Bit::A),
),
0x3..=0x6 => self.decode_0x0_to_0x3_commons(opcode)?,
0x7 => Instructions::RLC(InstParam::Register8Bit(Register8Bit::A)),
0x7 => Instructions::RLCA(),
0x8 => Instructions::LD(
InstParam::Number16Bit(self.get_16bit_from_pc()),
InstParam::Register16Bit(Register16Bit::SP),
Expand All @@ -168,7 +168,7 @@ impl CPU {
InstParam::Register16Bit(Register16Bit::BC),
),
0xB..=0xE => self.decode_0x0_to_0x3_commons(opcode)?,
0xF => Instructions::RRC(InstParam::Register8Bit(Register8Bit::A)),
0xF => Instructions::RRCA(),
_ => self.not_implemented(opcode)?,
},
0x1 => match tail {
Expand All @@ -179,7 +179,7 @@ impl CPU {
InstParam::Register8Bit(Register8Bit::A),
),
0x3..=0x6 => self.decode_0x0_to_0x3_commons(opcode)?,
0x7 => Instructions::RL(InstParam::Register8Bit(Register8Bit::A)),
0x7 => Instructions::RLA(),
0x8 => Instructions::JR(
InstParam::ConditionCodes(InstructionCondition::SkipConditionCodes),
InstParam::SignedNumber8Bit(self.get_8bit_from_pc() as i8),
Expand All @@ -190,7 +190,7 @@ impl CPU {
InstParam::Register16Bit(Register16Bit::DE),
),
0xB..=0xE => self.decode_0x0_to_0x3_commons(opcode)?,
0xF => Instructions::RR(InstParam::Register8Bit(Register8Bit::A)),
0xF => Instructions::RRA(),
_ => self.not_implemented(opcode)?,
},
0x2 => match tail {
Expand Down
4 changes: 4 additions & 0 deletions src/cpu/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,13 @@ pub enum Instructions {
RST(InstParam),

RL(InstParam),
RLA(),
RLC(InstParam),
RLCA(),
RR(InstParam),
RRA(),
RRC(InstParam),
RRCA(),
SLA(InstParam),
SRL(InstParam),
SRA(InstParam),
Expand Down
18 changes: 8 additions & 10 deletions src/cpu/instructions/arithmetic_and_logic/dec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,17 @@ impl CPU {
/// decrements the 8bit_register
pub fn dec_r8(&mut self, register: Register8Bit) -> InstructionResult {
let r8_value = self.get_8bit_register(register);
let (value,overflow) = r8_value.overflowing_sub(1);
let tail = r8_value & 0xF;
self.set_8bit_register(register, value);
let (result,_) = r8_value.overflowing_sub(1);
self.set_8bit_register(register, result);


InstructionResult {
cycles: 1,
bytes: 1,
condition_codes: ConditionCodes {
zero: if value == 0 {FlagState::Set} else {FlagState::Unset},
zero: if result == 0 {FlagState::Set} else {FlagState::Unset},
subtract: FlagState::Set,
half_carry: if tail == 0 {FlagState::Set} else {FlagState::Unset},
half_carry: if ((r8_value ^ 1) & 0x10) != (result & 0x10) {FlagState::Set} else {FlagState::Unset},
carry: FlagState::NotAffected,
},
}
Expand All @@ -39,17 +38,16 @@ impl CPU {
pub fn dec_hl(&mut self) -> InstructionResult {
let addr = self.get_16bit_register(Register16Bit::HL);
let r8_value = self.memory.read_byte(addr);
let (value,overflow) = r8_value.overflowing_sub(1);
self.memory.write_byte(addr, value);
let tail = r8_value & 0xF;
let (result,_) = r8_value.overflowing_sub(1);
self.memory.write_byte(addr, result);

InstructionResult {
cycles: 3,
bytes: 1,
condition_codes: ConditionCodes {
zero: if value == 0 {FlagState::Set} else {FlagState::Unset},
zero: if result == 0 {FlagState::Set} else {FlagState::Unset},
subtract: FlagState::Set,
half_carry: if tail == 0 {FlagState::Set} else {FlagState::Unset},
half_carry: if ((r8_value ^ 1) & 0x10) != (result & 0x10) {FlagState::Set} else {FlagState::Unset},
carry: FlagState::NotAffected,
},
}
Expand Down
29 changes: 22 additions & 7 deletions src/cpu/instructions/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,28 @@ impl CPU {

pub fn daa(&mut self) -> InstructionResult {
let mut value = self.get_8bit_register(Register8Bit::A);
let mut carry = false;
if (value & 0x0F) > 9 {
value = value.wrapping_add(6); //caused overflow on testrom 1, daa doesn't seem to work correctly yet
let mut daa_correction = 0;
let mut set_carry = false;
//currently set flags
let half_carry = self.is_half_carry_flag_set();
let carry = self.is_carry_flag_set();
let subtraction = self.is_subtraction_flag_set();

if half_carry || (!subtraction && (value & 0xf) > 9) {
daa_correction |= 0x6;
}
if (value & 0xF0) > 0x90 || (self.is_carry_flag_set() && (value & 0x0F) > 9) {
(value, carry) = value.overflowing_add(0x60);
if carry || (!subtraction && value > 0x99) {
daa_correction |= 0x60;
set_carry = true;
}
if subtraction {
(value,_) = value.overflowing_sub(daa_correction);
}else {
(value,_) = value.overflowing_add(daa_correction);
}



self.set_8bit_register(Register8Bit::A, value);
InstructionResult {
cycles: 1,
Expand All @@ -110,7 +125,7 @@ impl CPU {
},
subtract: FlagState::NotAffected,
half_carry: FlagState::Unset,
carry: if carry {
carry: if set_carry {
FlagState::Set
} else {
FlagState::Unset
Expand All @@ -124,7 +139,7 @@ impl CPU {
cycles: 1,
bytes: 1,
condition_codes: ConditionCodes {
zero: FlagState::Unset,
zero: FlagState::NotAffected,
subtract: FlagState::Unset,
half_carry: FlagState::Unset,
carry: FlagState::Set,
Expand Down
25 changes: 9 additions & 16 deletions src/cpu/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,35 +242,28 @@ impl CPU {
}
_ => return Err(format!("SWAP with {:?} not implemented", target)),
},
Instructions::RLA() =>self.rl_a(),
Instructions::RL(target) => match target {
InstParam::Register8Bit(register) => match register {
Register8Bit::A => self.rl_a(),
_ => self.rl_r8(*register),
},
InstParam::Register8Bit(register) => self.rl_r8(*register),
InstParam::Register16Bit(Register16Bit::HL) => self.rl_hl(),
_ => return Err(format!("SWAP with {:?} not implemented", target)),
},

Instructions::RLCA() => self.rl_c_a(),//RLCA and RLC A are two different instructions
Instructions::RLC(target) => match target {
InstParam::Register8Bit(register) => match register {
Register8Bit::A => self.rl_c_a(),
_ => self.rl_c_r8(*register),
},
InstParam::Register8Bit(register) => self.rl_c_r8(*register),
InstParam::Register16Bit(Register16Bit::HL) => self.rl_c_hl(),
_ => return Err(format!("RLC with {:?} not implemented", target)),
},
Instructions::RRA() => self.rr_a(),
Instructions::RR(target) => match target {
InstParam::Register8Bit(register) => match register {
Register8Bit::A => self.rr_a(),
_ => self.rr_r8(*register),
},
InstParam::Register8Bit(register) => self.rr_r8(*register),
InstParam::Register16Bit(Register16Bit::HL) => self.rr_hl(),
_ => return Err(format!("SWAP with {:?} not implemented", target)),
},
Instructions::RRCA() => self.rr_c_a(),//RRCA and RRC A are two different instructions
Instructions::RRC(target) => match target {
InstParam::Register8Bit(register) => match register {
Register8Bit::A => self.rr_c_a(),
_ => self.rr_c_r8(*register),
},
InstParam::Register8Bit(register) => self.rr_c_r8(*register),
InstParam::Register16Bit(Register16Bit::HL) => self.rr_c_hl(),
_ => return Err(format!("SWAP with {:?} not implemented", target)),
},
Expand Down

0 comments on commit 72411db

Please sign in to comment.