diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml
index 72e7244..fc066c9 100644
--- a/.idea/dictionaries/project.xml
+++ b/.idea/dictionaries/project.xml
@@ -5,6 +5,12 @@
adcn
addhl
addsp
+ dechl
+ inchl
+ jpcc
+ jphl
+ jrcc
+ reti
rrca
rrla
diff --git a/src/instructions.rs b/src/instructions.rs
index 45ee611..826be15 100644
--- a/src/instructions.rs
+++ b/src/instructions.rs
@@ -1,5 +1,5 @@
+use crate::registers::FlagsRegister;
use crate::registers::Registers;
-
struct CPU {
registers: Registers,
pc: u16,
@@ -19,12 +19,46 @@ impl MemoryBus {
}
}
-
+#[derive(Clone, Copy)]
enum Target {
U8Register(TargetRegister),
U16Register(TargetU16Register),
Address(u16),
}
+#[derive(Clone, Copy)]
+enum Condition {
+ NZ, // Not Zero
+ Z, // Zero
+ NC, // Not Carry
+ C, // Carry
+ None
+}
+
+#[derive(Clone, Copy)]
+enum LoadTarget{
+ CopyR8R8(TargetRegister, TargetRegister),
+ CopyR8N8(TargetRegister, u8),
+ CopyR16N16(TargetU16Register, u16),
+ CopyHLR8(TargetRegister),
+ CopyHLN8(u8),
+ CopyR8HL(TargetRegister),
+ CopyR16A(TargetU16Register),
+ CopyN16A(u16),
+ CopyHN16A(u16),
+ CopyHCA,
+ CopyAR16(TargetU16Register),
+ CopyAN16(u16),
+ CopyHAN16(u16),
+ CopyHAC,
+ CopyHLIA,
+ CopyHLDA,
+ CopyAHLD,
+ CopyAHLI,
+ CopySPN16(u16),
+ CopyN16SP(u16),
+ CopyHLSPE8(i8),
+ CopySPHL,
+}
enum Instruction {
@@ -34,27 +68,60 @@ enum Instruction {
ADDSP(u8),
AND(Target),
BIT(u8, Target),
- CALL(u16),
-
- SUB(TargetRegister),
- SBC(TargetRegister),
-
- OR(TargetRegister),
- XOR(TargetRegister),
- CP(TargetRegister),
- INC(TargetRegister),
- DEC(TargetRegister),
+ CALL(Condition, u16),
CCF,
- SCF,
- RRA,
- RLA,
- RRCA,
+ CP(Target),
CPL,
-
+ DAA,
+ DEC(Target),
+ DECHL(TargetU16Register),
+ DI,
+ EI,
+ HALT,
+ INC(Target),
+ INCHL(TargetU16Register),
+ JP(Condition, u16),
+ JPHL,
+ JR(Condition, i8),
+ LD(LoadTarget),
+ NOP,
+ OR(Target),
+ POP(TargetU16Register),
+ PUSH(TargetU16Register),
+ RES(u8, Target),
+ RET(Condition),
+ RETI,
+ RL(Target),
+ RLC(Target),
+ RR(Target),
+ RRC(Target),
+ RST(u8),
+ SBC(Target),
+ SCF,
+ SET(u8, Target),
+ SLA(Target),
+ SRA(Target),
+ SRL(Target),
+ STOP,
+ SUB(Target),
+ SWAP(Target),
+ XOR(Target),
}
+#[derive(Clone, Copy)]
enum TargetRegister { A, B, C, D, E, H, L, }
+#[derive(Clone, Copy)]
enum TargetU16Register {AF, BC, DE, HL, SP, PC}
impl CPU {
+ fn check_condition(&self, condition: Condition) -> bool {
+ match condition {
+ Condition::NZ => !self.registers.f.zero,
+ Condition::Z => self.registers.f.zero,
+ Condition::NC => !self.registers.f.carry,
+ Condition::C => self.registers.f.carry,
+ Condition::None => true,
+ }
+ }
+
fn get_u8_reg_value(&mut self, target: TargetRegister) -> u8 {
match target {
TargetRegister::A => { self.registers.a }
@@ -66,6 +133,17 @@ impl CPU {
TargetRegister::L => { self.registers.l }
}
}
+ fn set_u8_reg_value(&mut self, target: TargetRegister, value: u8) {
+ match target {
+ TargetRegister::A => { self.registers.a = value }
+ TargetRegister::B => { self.registers.b = value }
+ TargetRegister::C => { self.registers.c = value }
+ TargetRegister::D => { self.registers.d = value }
+ TargetRegister::E => { self.registers.e = value }
+ TargetRegister::H => { self.registers.h = value }
+ TargetRegister::L => { self.registers.l = value }
+ }
+ }
fn get_u16_reg_value(&mut self, target: TargetU16Register) -> u16 {
match target {
TargetU16Register::AF => {self.registers.get_af()}
@@ -76,17 +154,50 @@ impl CPU {
TargetU16Register::PC => {self.pc}
}
}
+ fn set_u16_reg_value(&mut self, target: TargetU16Register, value: u16) {
+ match target {
+ TargetU16Register::AF => {self.registers.set_af(value)}
+ TargetU16Register::BC => {self.registers.set_bc(value)}
+ TargetU16Register::DE => {self.registers.set_de(value)}
+ TargetU16Register::HL => {self.registers.set_hl(value)}
+ TargetU16Register::SP => {self.sp=value}
+ TargetU16Register::PC => {self.pc=value}
+ }
+ }
+ fn push_stack(&mut self, value: u16) {
+ let low = (value & 0xFF) as u8;
+ let high = (value >> 8) as u8;
+ self.bus.write_byte(self.sp - 1, high);
+ self.bus.write_byte(self.sp - 2, low);
+ self.sp = self.sp.wrapping_sub(2);
+ }
+ fn pop_stack(&mut self) -> u16 {
+ let low = (self.bus.read_byte(self.sp) as u16) << 8;
+ let high = self.bus.read_byte(self.sp + 1) as u16;
+ self.sp = self.sp.wrapping_add(2);
+ high | low
+ }
fn get_target_value(&mut self, target: Target) -> u8 {
match target {
Target::U8Register(target_register) => { self.get_u8_reg_value(target_register) },
- Target::U16Register(target_register) => {
+ Target::U16Register(target_register) => {
let address = self.get_u16_reg_value(target_register);
- self.bus.read_byte(address)
+ self.bus.read_byte(address)
},
Target::Address(address) => { self.bus.read_byte(address) },
}
}
+ fn set_target_value(&mut self, target: Target, value: u8) {
+ match target {
+ Target::U8Register(target_register) => { self.set_u8_reg_value(target_register, value) },
+ Target::U16Register(target_register) => {
+ let address = self.get_u16_reg_value(target_register);
+ self.bus.write_byte(address, value)
+ },
+ Target::Address(address) => { self.bus.write_byte(address, value) },
+ }
+ }
///
fn execute(&mut self, instruction: Instruction) {
@@ -142,33 +253,311 @@ impl CPU {
self.registers.f.subtract = false;
self.registers.f.half_carry = true;
}
- Instruction::CALL(address) => {
- // Decrement stack pointer
- self.sp = self.sp.wrapping_sub(2);
-
- let pc = self.pc;
- self.bus.write_byte(self.sp + 1, ((pc >> 8) & 0xFF) as u8);
- self.bus.write_byte(self.sp, (pc & 0xFF) as u8);
-
- // Jump to the target address
- self.pc = address;
+ Instruction::CALL(condition, address) => {
+ if self.check_condition(condition) {
+ self.sp = self.sp.wrapping_sub(2);
+ let pc = self.pc;
+ self.bus.write_byte(self.sp + 1, ((pc >> 8) & 0xFF) as u8);
+ self.bus.write_byte(self.sp, (pc & 0xFF) as u8);
+ self.pc = address;
+ }
}
-
-
-
-
-
- Instruction::SUB(target) => {
- let value = self.get_u8_reg_value(target);
+ Instruction::CCF => {
+ self.registers.f.subtract = false;
+ self.registers.f.half_carry = false;
+ self.registers.f.carry = !self.registers.f.carry;
+ }
+ Instruction::CP(target) => {
+ let value = self.get_target_value(target);
let (new_value, did_overflow) = self.registers.a.overflowing_sub(value);
- self.registers.a = new_value;
self.registers.f.zero = new_value == 0;
self.registers.f.subtract = true;
self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
}
+ Instruction::CPL => {
+ self.registers.a = !self.registers.a;
+ self.registers.f.subtract = true;
+ self.registers.f.half_carry = true;
+ }
+ Instruction::DAA => {
+ let new_value;
+ let did_overflow;
+ let mut adjustment: u8 = 0;
+ if self.registers.f.subtract {
+ if self.registers.f.half_carry {
+ adjustment += 0x6;
+ }
+ if self.registers.f.carry {
+ adjustment += 0x60;
+ }
+ (new_value, did_overflow) = self.registers.a.overflowing_sub(adjustment);
+ } else {
+ if self.registers.f.half_carry || self.registers.a & 0xF > 0x9 {
+ adjustment += 0x6;
+ }
+ if self.registers.f.carry || self.registers.a > 0x99 {
+ adjustment += 0x60;
+ }
+ (new_value, did_overflow) = self.registers.a.overflowing_add(adjustment);
+ }
+ self.registers.a = new_value;
+ self.registers.f.carry = did_overflow;
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::DEC(target) => {
+ match target {
+ Target::U8Register(target) => {
+ let value = self.get_u8_reg_value(target);
+ let (new_value, _) = value.overflowing_sub(1);
+ self.set_u8_reg_value(target, new_value);
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.subtract = true;
+ self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF;
+ }
+ Target::U16Register(target) => {
+ let value = self.get_u16_reg_value(target);
+ let new_value = value.wrapping_sub(1);
+ self.set_u16_reg_value(target, new_value);
+ }
+ Target::Address(_) => {}
+ }
+ }
+ Instruction::DECHL(register) => {
+ let target = Target::U16Register(register);
+ let value = self.get_target_value(target);
+ let new_value = value.wrapping_sub(1);
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.subtract = true;
+ self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF;
+ }
+ Instruction::DI => {}
+ Instruction::EI => {}
+ Instruction::HALT => {todo!();}
+
+ Instruction::INC(target) => {
+ match target {
+ Target::U8Register(target) => {
+ let value = self.get_u8_reg_value(target);
+ let (new_value, _) = value.overflowing_add(1);
+ self.set_u8_reg_value(target, new_value);
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.subtract = false;
+ self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF;
+ }
+ Target::U16Register(target) => {
+ let value = self.get_u16_reg_value(target);
+ let new_value = value.wrapping_add(1);
+ self.set_u16_reg_value(target, new_value);
+ }
+ Target::Address(_) => {}
+ }
+ }
+ Instruction::INCHL(register) => {
+ let target = Target::U16Register(register);
+ let value = self.get_target_value(target);
+ let new_value = value.wrapping_add(1);
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.subtract = true;
+ self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF;
+ }
+ Instruction::JP(condition, address) => {
+ if self.check_condition(condition) {
+ self.pc = address;
+ }
+ }
+ Instruction::JPHL => {
+ self.pc = self.registers.get_hl();
+ }
+ Instruction::JR(condition, offset) => {
+ if self.check_condition(condition) {
+ self.pc = if offset.is_negative() {
+ self.pc.wrapping_sub(offset.abs() as u16)
+ } else {
+ self.pc.wrapping_add(offset as u16)
+ }
+ }
+ }
+ Instruction::LD(target) => {
+ match target {
+ LoadTarget::CopyR8R8(dest_register, source_register) => {
+ let value = self.get_u8_reg_value(source_register);
+ self.set_u8_reg_value(dest_register, value);
+ }
+ LoadTarget::CopyR8N8(dest_register, value) => {
+ self.set_u8_reg_value(dest_register, value);
+ }
+ LoadTarget::CopyR16N16(dest_register, value) => {
+ self.set_u16_reg_value(dest_register, value);
+ }
+ LoadTarget::CopyHLR8(source_register) => {
+ let value = self.get_u8_reg_value(source_register);
+ let address = self.registers.get_hl();
+ self.bus.write_byte(address, value);
+ }
+ LoadTarget::CopyHLN8(value) => {
+ let address = self.registers.get_hl();
+ self.bus.write_byte(address, value);
+ }
+ LoadTarget::CopyR8HL(dest_register) => {
+ let address = self.registers.get_hl();
+ let value = self.bus.read_byte(address);
+ self.set_u8_reg_value(dest_register, value);
+ }
+ LoadTarget::CopyR16A(dest_register) => {
+ let address = self.get_u16_reg_value(dest_register);
+ self.bus.write_byte(address, self.registers.a);
+ }
+ LoadTarget::CopyN16A(address) => {
+ self.bus.write_byte(address, self.registers.a);
+ }
+ LoadTarget::CopyHN16A(address) => {
+ if address >= 0xFF00 {
+ self.bus.write_byte(address, self.registers.a)
+ }
+ }
+ LoadTarget::CopyHCA => {
+ let address = 0xFF00 + self.registers.c as u16;
+ self.bus.write_byte(address, self.registers.a)
+ }
+ LoadTarget::CopyAR16(source_register) => {
+ let address = self.get_u16_reg_value(source_register);
+ self.registers.a = self.bus.read_byte(address);
+ }
+ LoadTarget::CopyAN16(address) => {
+ self.registers.a = self.bus.read_byte(address);
+ }
+ LoadTarget::CopyHAN16(address) => {
+ if address >= 0xFF00 {
+ self.registers.a = self.bus.read_byte(address)
+ }
+ }
+ LoadTarget::CopyHAC => {
+ self.registers.a = self.bus.read_byte(0xFF00+self.registers.c as u16)
+ }
+ LoadTarget::CopyHLIA => {
+ let address = self.registers.get_hl();
+ self.bus.write_byte(address, self.registers.a);
+ self.registers.set_hl(address.wrapping_add(1));
+ }
+ LoadTarget::CopyHLDA => {
+ let address = self.registers.get_hl();
+ self.bus.write_byte(address, self.registers.a);
+ self.registers.set_hl(address.wrapping_sub(1));
+ }
+ LoadTarget::CopyAHLI => {
+ let address = self.registers.get_hl();
+ self.registers.a = self.bus.read_byte(address);
+ self.registers.set_hl(address.wrapping_add(1));
+ }
+ LoadTarget::CopyAHLD => {
+ let address = self.registers.get_hl();
+ self.registers.a = self.bus.read_byte(address);
+ self.registers.set_hl(address.wrapping_sub(1));
+ }
+ LoadTarget::CopySPN16(value) => {
+ self.sp = value;
+ }
+ LoadTarget::CopyN16SP(address) => {
+ self.bus.write_byte(address, (0xF & self.sp) as u8);
+ self.bus.write_byte(address + 1, (self.sp >> 8) as u8);
+ }
+ LoadTarget::CopyHLSPE8(value) => {
+
+ let new_value = match value.is_negative() {
+ true => { self.sp.wrapping_sub(value.abs() as u16) }
+ false => { self.sp.wrapping_add(value as u16) }
+ };
+ self.registers.set_hl(new_value);
+ self.registers.f.zero = false;
+ self.registers.f.subtract = false;
+ self.registers.f.carry = (new_value & 0xFF) + (self.sp & 0xFF) > 0xFF;
+ self.registers.f.half_carry = (new_value & 0xF) + (self.sp & 0xF) > 0xF;
+
+ }
+ LoadTarget::CopySPHL => {
+ self.sp = self.registers.get_hl();
+ }
+ }
+ }
+ Instruction::NOP => {}
+ Instruction::OR(target) => {
+ let value = self.get_target_value(target);
+ self.registers.a = value | self.registers.a;
+ self.registers.f.zero = self.registers.a == 0;
+ self.registers.f.subtract = false;
+ self.registers.f.carry = false;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::POP(target) => {
+ let value = self.pop_stack();
+ self.set_u16_reg_value(target, value);
+ }
+ Instruction::PUSH(target) => {
+ let value = self.get_u16_reg_value(target);
+ self.push_stack(value);
+ }
+ Instruction::RES(bit, target) => {
+ let mut value = self.get_target_value(target);
+ value &= !(1 << bit);
+ self.set_target_value(target, value);
+ }
+ Instruction::RET(condition) => {
+ if self.check_condition(condition) {
+ self.pc = self.pop_stack();
+ }
+ }
+ Instruction::RETI => {
+ self.pc = self.pop_stack();
+ }
+ Instruction::RL(target) => {
+ let old_value = self.get_target_value(target);
+ let old_carry = self.registers.f.carry;
+ self.registers.f.carry = old_value & 0x80 == 0x80;
+ let new_value = (self.registers.a << 1) | (if old_carry { 0x01 } else { 0 });
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = false;
+ self.registers.f.subtract = false;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::RLC(target) => {
+ let old_value = self.get_target_value(target);
+ self.registers.f.carry = old_value & 0x80 == 0x80;
+ let new_value = (self.registers.a << 1) | (if self.registers.f.carry { 0x1 } else { 0 });
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = false;
+ self.registers.f.subtract = false;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::RR(target) => {
+ let old_value = self.get_target_value(target);
+ let old_carry = self.registers.f.carry;
+ self.registers.f.carry = old_value & 0x1 == 0x1;
+ let new_value = (self.registers.a >> 1) | (if old_carry { 0x80 } else { 0 });
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = false;
+ self.registers.f.subtract = false;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::RRC(target) => {
+ let old_value = self.get_target_value(target);
+ self.registers.f.carry = old_value & 0x1 == 0x1;
+ let new_value = (self.registers.a >> 1) | (if self.registers.f.carry { 0x80 } else { 0 });
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = false;
+ self.registers.f.subtract = false;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::RST(idx) => {
+ self.push_stack(self.pc);
+ let address = self.bus.read_byte((idx as u16) * 8) as u16;
+ self.pc = address;
+ }
Instruction::SBC(target) => {
- let value = self.get_u8_reg_value(target);
+ let value = self.get_target_value(target);
let (mut new_value, did_overflow) = self.registers.a.overflowing_sub(value);
new_value -= did_overflow as u8;
self.registers.a = new_value;
@@ -177,165 +566,72 @@ impl CPU {
self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
}
-
- Instruction::OR(target) => {
- let value = self.get_u8_reg_value(target);
- self.registers.a = value | self.registers.a;
- self.registers.f.zero = self.registers.a == 0;
+ Instruction::SCF => {
+ self.registers.f.carry = true;
+ self.registers.f.subtract = false;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::SET(bit, target) => {
+ let mut value = self.get_target_value(target);
+ value |= 1 << bit;
+ self.set_target_value(target, value);
+ }
+ Instruction::SLA(target) => {
+ let value = self.get_target_value(target);
+ let new_value = value << 1;
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.subtract = false;
+ self.registers.f.carry = value & 0x80 == 0x80;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::SRA(target) => {
+ let value = self.get_target_value(target);
+ let new_value = value >> 1 | (if value & 0x80 == 0x80 { 0x80 } else { 0 });
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.subtract = false;
+ self.registers.f.carry = value & 0x80 == 0x80;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::SRL(target) => {
+ let value = self.get_target_value(target);
+ let new_value = value >> 1;
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.subtract = false;
+ self.registers.f.carry = value & 0x1 == 0x1;
+ self.registers.f.half_carry = false;
+ }
+ Instruction::STOP => {
+
+ }
+ Instruction::SUB(target) => {
+ let value = self.get_target_value(target);
+ let (new_value, did_overflow) = self.registers.a.overflowing_sub(value);
+ self.registers.a = new_value;
+ self.registers.f.zero = new_value == 0;
+ self.registers.f.subtract = true;
+ self.registers.f.carry = did_overflow;
+ self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
+ }
+ Instruction::SWAP(target) => {
+ let value = self.get_target_value(target);
+ let new_value = ((value & 0xF0) >> 4) | ((value & 0x0F) << 4);
+ self.set_target_value(target, new_value);
+ self.registers.f.zero = new_value == 0;
self.registers.f.subtract = false;
self.registers.f.carry = false;
self.registers.f.half_carry = false;
- }
+ }
Instruction::XOR(target) => {
- let value = self.get_u8_reg_value(target);
+ let value = self.get_target_value(target);
self.registers.a = value ^ self.registers.a;
self.registers.f.zero = self.registers.a == 0;
self.registers.f.subtract = false;
self.registers.f.carry = false;
self.registers.f.half_carry = false;
}
- Instruction::CP(target) => {
- let value = self.get_u8_reg_value(target);
- let (new_value, did_overflow) = self.registers.a.overflowing_sub(value);
- self.registers.f.zero = new_value == 0;
- self.registers.f.subtract = true;
- self.registers.f.carry = did_overflow;
- self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
- }
- Instruction::INC(target) => {
- let (value, new_value) = match target {
- TargetRegister::A => {
- let value = self.registers.a;
- let (new_value, _) = value.overflowing_add(1);
- self.registers.a = new_value;
- (value, new_value)
- },
- TargetRegister::B => {
- let value = self.registers.b;
- let (new_value, _) = value.overflowing_add(1);
- self.registers.b = new_value;
- (value, new_value)
- },
- TargetRegister::C => {
- let value = self.registers.c;
- let (new_value, _) = value.overflowing_add(1);
- self.registers.c = new_value;
- (value, new_value)
- },
- TargetRegister::D => {
- let value = self.registers.d;
- let (new_value, _) = value.overflowing_add(1);
- self.registers.d = new_value;
- (value, new_value)
- },
- TargetRegister::E => {
- let value = self.registers.e;
- let (new_value, _) = value.overflowing_add(1);
- self.registers.e = new_value;
- (value, new_value)
- },
- TargetRegister::H => {
- let value = self.registers.h;
- let (new_value, _) = value.overflowing_add(1);
- self.registers.h = new_value;
- (value, new_value)
- },
- TargetRegister::L => {
- let value = self.registers.l;
- let (new_value, _) = value.overflowing_add(1);
- self.registers.l = new_value;
- (value, new_value)
- }
- };
- self.registers.f.zero = new_value == 0;
- self.registers.f.subtract = false;
- self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF;
- }
- Instruction::DEC(target) => {
- let (value, new_value) = match target {
- TargetRegister::A => {
- let value = self.registers.a;
- let (new_value, _) = value.overflowing_sub(1);
- self.registers.a = new_value;
- (value, new_value)
- },
- TargetRegister::B => {
- let value = self.registers.b;
- let (new_value, _) = value.overflowing_sub(1);
- self.registers.b = new_value;
- (value, new_value)
- },
- TargetRegister::C => {
- let value = self.registers.c;
- let (new_value, _) = value.overflowing_sub(1);
- self.registers.c = new_value;
- (value, new_value)
- },
- TargetRegister::D => {
- let value = self.registers.d;
- let (new_value, _) = value.overflowing_sub(1);
- self.registers.d = new_value;
- (value, new_value)
- },
- TargetRegister::E => {
- let value = self.registers.e;
- let (new_value, _) = value.overflowing_sub(1);
- self.registers.e = new_value;
- (value, new_value)
- },
- TargetRegister::H => {
- let value = self.registers.h;
- let (new_value, _) = value.overflowing_sub(1);
- self.registers.h = new_value;
- (value, new_value)
- },
- TargetRegister::L => {
- let value = self.registers.l;
- let (new_value, _) = value.overflowing_sub(1);
- self.registers.l = new_value;
- (value, new_value)
- }
- };
- self.registers.f.zero = new_value == 0;
- self.registers.f.subtract = true;
- self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF;
- }
- Instruction::CCF => {
- self.registers.f.carry = !self.registers.f.carry;
- }
- Instruction::SCF => {
- self.registers.f.carry = true;
- }
- Instruction::RRA => {
- let old_carry = self.registers.f.carry;
- self.registers.f.carry = self.registers.a & 0x1 == 0x1;
- self.registers.a = (self.registers.a >> 1) | (if old_carry { 0x80 } else { 0 });
- self.registers.f.zero = false;
- self.registers.f.subtract = false;
- self.registers.f.half_carry = false;
- }
- Instruction::RLA => {
- let old_carry = self.registers.f.carry;
- self.registers.f.carry = self.registers.a & 0x80 == 0x80;
- self.registers.a = (self.registers.a << 1) | (if old_carry { 0x01 } else { 0 });
- self.registers.f.zero = false;
- self.registers.f.subtract = false;
- self.registers.f.half_carry = false;
- }
- Instruction::RRCA => {
- self.registers.f.carry = self.registers.a & 0x1 == 0x1;
- self.registers.a = self.registers.a >> 1;
- self.registers.f.zero = false;
- self.registers.f.subtract = false;
- self.registers.f.half_carry = false;
- }
- Instruction::CPL => {
- self.registers.a = !self.registers.a;
- self.registers.f.subtract = true;
- self.registers.f.half_carry = true;
- }
-
-
}
}
}