chore: refactor parts of instruction.rs
This commit is contained in:
parent
501d93c37b
commit
e5fb07c4d1
|
@ -150,14 +150,14 @@ impl Instruction {
|
||||||
cpu.write_byte(addr, a);
|
cpu.write_byte(addr, a);
|
||||||
}
|
}
|
||||||
InstrRegisterPair::IncrementHL => {
|
InstrRegisterPair::IncrementHL => {
|
||||||
// LD (HL+), A | Put A into memory address HL, then increment HL
|
// LD (HL+), A | Put A into byte at address HL, then increment HL
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
cpu.write_byte(addr, a);
|
cpu.write_byte(addr, a);
|
||||||
|
|
||||||
cpu.set_register_pair(RegisterPair::HL, addr + 1);
|
cpu.set_register_pair(RegisterPair::HL, addr + 1);
|
||||||
}
|
}
|
||||||
InstrRegisterPair::DecrementHL => {
|
InstrRegisterPair::DecrementHL => {
|
||||||
// LD (HL-), A | Put A into memory address HL, then decrement HL
|
// LD (HL-), A | Put A into byte at address HL, then decrement HL
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
cpu.write_byte(addr, a);
|
cpu.write_byte(addr, a);
|
||||||
|
|
||||||
|
@ -180,8 +180,8 @@ impl Instruction {
|
||||||
// LD A, (HL+) | Put value at address HL into A, then increment HL
|
// LD A, (HL+) | Put value at address HL into A, then increment HL
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let byte = cpu.read_byte(addr);
|
let byte = cpu.read_byte(addr);
|
||||||
cpu.set_register(Register::A, byte);
|
|
||||||
|
|
||||||
|
cpu.set_register(Register::A, byte);
|
||||||
cpu.set_register_pair(RegisterPair::HL, addr + 1);
|
cpu.set_register_pair(RegisterPair::HL, addr + 1);
|
||||||
}
|
}
|
||||||
InstrRegisterPair::DecrementHL => {
|
InstrRegisterPair::DecrementHL => {
|
||||||
|
@ -344,13 +344,12 @@ impl Instruction {
|
||||||
Instruction::ADD(lhs, rhs) => match (lhs, rhs) {
|
Instruction::ADD(lhs, rhs) => match (lhs, rhs) {
|
||||||
(MATHTarget::RegisterPair(RegisterPair::HL), MATHTarget::RegisterPair(pair)) => {
|
(MATHTarget::RegisterPair(RegisterPair::HL), MATHTarget::RegisterPair(pair)) => {
|
||||||
// ADD HL, rp[p] | add register pair to HL.
|
// ADD HL, rp[p] | add register pair to HL.
|
||||||
|
use RegisterPair::*;
|
||||||
|
|
||||||
let mut flags: Flags = *cpu.flags();
|
let mut flags: Flags = *cpu.flags();
|
||||||
|
|
||||||
match pair {
|
match pair {
|
||||||
RegisterPair::BC
|
BC | DE | HL | SP => {
|
||||||
| RegisterPair::DE
|
|
||||||
| RegisterPair::HL
|
|
||||||
| RegisterPair::SP => {
|
|
||||||
let hl_value = cpu.register_pair(RegisterPair::HL);
|
let hl_value = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.register_pair(pair);
|
let value = cpu.register_pair(pair);
|
||||||
let sum = Self::add_u16s(hl_value, value, &mut flags);
|
let sum = Self::add_u16s(hl_value, value, &mut flags);
|
||||||
|
@ -582,32 +581,27 @@ impl Instruction {
|
||||||
Instruction::ADC(target) => match target {
|
Instruction::ADC(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
// ADC A, r[z] | Add register r[z] plus the Carry flag to A
|
// ADC A, r[z] | Add register r[z] plus the Carry flag to A
|
||||||
// FIXME: Do I Add register A as well?
|
use InstrRegister::*;
|
||||||
|
|
||||||
let mut flags: Flags = *cpu.flags();
|
let mut flags: Flags = *cpu.flags();
|
||||||
let a_value = cpu.register(Register::A);
|
let a_value = cpu.register(Register::A);
|
||||||
let cycles: Cycles;
|
|
||||||
let sum;
|
|
||||||
|
|
||||||
match reg {
|
let (cycles, sum) = match reg {
|
||||||
InstrRegister::B
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::C
|
|
||||||
| InstrRegister::D
|
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let value = cpu.register(reg.to_register()) + (flags.c() as u8);
|
let value = cpu.register(reg.to_register()) + (flags.c() as u8);
|
||||||
sum = Self::add_u8s(a_value, value, &mut flags);
|
let sum = Self::add_u8s(a_value, value, &mut flags);
|
||||||
cycles = Cycles::new(4);
|
(Cycles::new(4), sum)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL));
|
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL))
|
||||||
sum = Self::add_u8s(a_value, value, &mut flags);
|
+ (flags.c() as u8);
|
||||||
cycles = Cycles::new(8);
|
let sum = Self::add_u8s(a_value, value, &mut flags);
|
||||||
|
(Cycles::new(8), sum)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
cpu.set_flags(flags);
|
|
||||||
cpu.set_register(Register::A, sum);
|
cpu.set_register(Register::A, sum);
|
||||||
|
cpu.set_flags(flags);
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
MATHTarget::ImmediateByte(n) => {
|
MATHTarget::ImmediateByte(n) => {
|
||||||
|
@ -625,32 +619,26 @@ impl Instruction {
|
||||||
Instruction::SUB(target) => match target {
|
Instruction::SUB(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
// SUB r[z] | Subtract the value in register r[z] from register A, then store in A
|
// SUB r[z] | Subtract the value in register r[z] from register A, then store in A
|
||||||
|
use InstrRegister::*;
|
||||||
|
|
||||||
let mut flags: Flags = *cpu.flags();
|
let mut flags: Flags = *cpu.flags();
|
||||||
let a_value = cpu.register(Register::A);
|
let a_value = cpu.register(Register::A);
|
||||||
let cycles: Cycles;
|
|
||||||
let diff;
|
|
||||||
|
|
||||||
match reg {
|
let (cycles, diff) = match reg {
|
||||||
InstrRegister::B
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::C
|
|
||||||
| InstrRegister::D
|
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let value = cpu.register(reg.to_register());
|
let value = cpu.register(reg.to_register());
|
||||||
diff = Self::sub_u8s(a_value, value, &mut flags);
|
let diff = Self::sub_u8s(a_value, value, &mut flags);
|
||||||
cycles = Cycles::new(4);
|
(Cycles::new(4), diff)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL));
|
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL));
|
||||||
diff = Self::sub_u8s(a_value, value, &mut flags);
|
let diff = Self::sub_u8s(a_value, value, &mut flags);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), diff)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
cpu.set_flags(flags);
|
|
||||||
cpu.set_register(Register::A, diff);
|
cpu.set_register(Register::A, diff);
|
||||||
|
cpu.set_flags(flags);
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
MATHTarget::ImmediateByte(n) => {
|
MATHTarget::ImmediateByte(n) => {
|
||||||
|
@ -668,29 +656,24 @@ impl Instruction {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
// SBC A, r[z] | Subtract the value from register r[z] from A, add the Carry flag and then store in A
|
// SBC A, r[z] | Subtract the value from register r[z] from A, add the Carry flag and then store in A
|
||||||
// FIXME: See ADC, is this a correct understanding of this Instruction
|
// FIXME: See ADC, is this a correct understanding of this Instruction
|
||||||
|
use InstrRegister::*;
|
||||||
|
|
||||||
let mut flags: Flags = *cpu.flags();
|
let mut flags: Flags = *cpu.flags();
|
||||||
let a_value = cpu.register(Register::A);
|
let a_value = cpu.register(Register::A);
|
||||||
let cycles: Cycles;
|
|
||||||
let diff;
|
|
||||||
|
|
||||||
match reg {
|
let (cycles, diff) = match reg {
|
||||||
InstrRegister::B
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::C
|
|
||||||
| InstrRegister::D
|
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let value = cpu.register(reg.to_register()) + (flags.c() as u8);
|
let value = cpu.register(reg.to_register()) + (flags.c() as u8);
|
||||||
diff = Self::sub_u8s(a_value, value, &mut flags);
|
let diff = Self::sub_u8s(a_value, value, &mut flags);
|
||||||
cycles = Cycles::new(4);
|
(Cycles::new(4), diff)
|
||||||
}
|
|
||||||
InstrRegister::IndirectHL => {
|
|
||||||
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL));
|
|
||||||
diff = Self::sub_u8s(a_value, value, &mut flags);
|
|
||||||
cycles = Cycles::new(8);
|
|
||||||
}
|
}
|
||||||
|
IndirectHL => {
|
||||||
|
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL))
|
||||||
|
+ (flags.c() as u8);
|
||||||
|
let diff = Self::sub_u8s(a_value, value, &mut flags);
|
||||||
|
(Cycles::new(8), diff)
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
cpu.set_register(Register::A, diff);
|
cpu.set_register(Register::A, diff);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
@ -748,29 +731,21 @@ impl Instruction {
|
||||||
Instruction::XOR(target) => match target {
|
Instruction::XOR(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
// XOR r[z] | Bitwise XOR register r[z] and register A, store in register A
|
// XOR r[z] | Bitwise XOR register r[z] and register A, store in register A
|
||||||
|
use InstrRegister::*;
|
||||||
|
|
||||||
let mut flags: Flags = *cpu.flags();
|
let mut flags: Flags = *cpu.flags();
|
||||||
let a_value = cpu.register(Register::A);
|
let a_value = cpu.register(Register::A);
|
||||||
let cycles: Cycles;
|
|
||||||
let result;
|
|
||||||
|
|
||||||
match reg {
|
let (cycles, result) = match reg {
|
||||||
InstrRegister::B
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::C
|
|
||||||
| InstrRegister::D
|
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let value = cpu.register(reg.to_register());
|
let value = cpu.register(reg.to_register());
|
||||||
result = a_value ^ value;
|
(Cycles::new(4), a_value ^ value)
|
||||||
cycles = Cycles::new(4);
|
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL));
|
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL));
|
||||||
result = a_value ^ value;
|
(Cycles::new(8), a_value ^ value)
|
||||||
cycles = Cycles::new(8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(result == 0, false, false, false);
|
flags.update(result == 0, false, false, false);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
@ -792,29 +767,21 @@ impl Instruction {
|
||||||
Instruction::OR(target) => match target {
|
Instruction::OR(target) => match target {
|
||||||
MATHTarget::Register(reg) => {
|
MATHTarget::Register(reg) => {
|
||||||
// OR r[z] | Bitwise OR register r[z] and register A, store in register A
|
// OR r[z] | Bitwise OR register r[z] and register A, store in register A
|
||||||
|
use InstrRegister::*;
|
||||||
|
|
||||||
let mut flags: Flags = *cpu.flags();
|
let mut flags: Flags = *cpu.flags();
|
||||||
let a_value = cpu.register(Register::A);
|
let a_value = cpu.register(Register::A);
|
||||||
let cycles: Cycles;
|
|
||||||
let result;
|
|
||||||
|
|
||||||
match reg {
|
let (cycles, result) = match reg {
|
||||||
InstrRegister::B
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::C
|
|
||||||
| InstrRegister::D
|
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let value = cpu.register(reg.to_register());
|
let value = cpu.register(reg.to_register());
|
||||||
result = a_value | value;
|
(Cycles::new(4), a_value | value)
|
||||||
cycles = Cycles::new(4);
|
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL));
|
let value = cpu.read_byte(cpu.register_pair(RegisterPair::HL));
|
||||||
result = a_value | value;
|
(Cycles::new(8), a_value | value)
|
||||||
cycles = Cycles::new(8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(result == 0, false, false, false);
|
flags.update(result == 0, false, false, false);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
@ -877,34 +844,38 @@ impl Instruction {
|
||||||
if !flags.z() {
|
if !flags.z() {
|
||||||
let addr = Self::pop(cpu);
|
let addr = Self::pop(cpu);
|
||||||
cpu.set_register_pair(RegisterPair::PC, addr);
|
cpu.set_register_pair(RegisterPair::PC, addr);
|
||||||
return Cycles::new(20);
|
Cycles::new(20)
|
||||||
}
|
} else {
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JumpCondition::Zero => {
|
JumpCondition::Zero => {
|
||||||
if flags.z() {
|
if flags.z() {
|
||||||
let addr = Self::pop(cpu);
|
let addr = Self::pop(cpu);
|
||||||
cpu.set_register_pair(RegisterPair::PC, addr);
|
cpu.set_register_pair(RegisterPair::PC, addr);
|
||||||
return Cycles::new(20);
|
Cycles::new(20)
|
||||||
}
|
} else {
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JumpCondition::NotCarry => {
|
JumpCondition::NotCarry => {
|
||||||
if !flags.c() {
|
if !flags.c() {
|
||||||
let addr = Self::pop(cpu);
|
let addr = Self::pop(cpu);
|
||||||
cpu.set_register_pair(RegisterPair::PC, addr);
|
cpu.set_register_pair(RegisterPair::PC, addr);
|
||||||
return Cycles::new(20);
|
Cycles::new(20)
|
||||||
}
|
} else {
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JumpCondition::Carry => {
|
JumpCondition::Carry => {
|
||||||
if flags.c() {
|
if flags.c() {
|
||||||
let addr = Self::pop(cpu);
|
let addr = Self::pop(cpu);
|
||||||
cpu.set_register_pair(RegisterPair::PC, addr);
|
cpu.set_register_pair(RegisterPair::PC, addr);
|
||||||
return Cycles::new(20);
|
Cycles::new(20)
|
||||||
}
|
} else {
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JumpCondition::Always => {
|
JumpCondition::Always => {
|
||||||
let addr = Self::pop(cpu);
|
let addr = Self::pop(cpu);
|
||||||
cpu.set_register_pair(RegisterPair::PC, addr);
|
cpu.set_register_pair(RegisterPair::PC, addr);
|
||||||
|
@ -917,14 +888,18 @@ impl Instruction {
|
||||||
// LD HL, SP + d | Add SP + d to register HL
|
// LD HL, SP + d | Add SP + d to register HL
|
||||||
let mut flags: Flags = *cpu.flags();
|
let mut flags: Flags = *cpu.flags();
|
||||||
let sum = Self::add_u16_i8(cpu.register_pair(RegisterPair::SP), d, &mut flags);
|
let sum = Self::add_u16_i8(cpu.register_pair(RegisterPair::SP), d, &mut flags);
|
||||||
|
|
||||||
cpu.set_register_pair(RegisterPair::HL, sum);
|
cpu.set_register_pair(RegisterPair::HL, sum);
|
||||||
|
cpu.set_flags(flags);
|
||||||
Cycles::new(12)
|
Cycles::new(12)
|
||||||
}
|
}
|
||||||
Instruction::POP(pair) => {
|
Instruction::POP(pair) => {
|
||||||
// POP rp2[p] | Pop from stack into register pair rp2[]
|
// POP rp2[p] | Pop from stack into register pair rp2[]
|
||||||
// Flags are set when we call cpu.set_register_pair(RegisterPair::AF, value);
|
// Flags are set when we call cpu.set_register_pair(RegisterPair::AF, value);
|
||||||
|
use RegisterPair::*;
|
||||||
|
|
||||||
match pair {
|
match pair {
|
||||||
RegisterPair::BC | RegisterPair::DE | RegisterPair::HL | RegisterPair::AF => {
|
BC | DE | HL | AF => {
|
||||||
let value = Self::pop(cpu);
|
let value = Self::pop(cpu);
|
||||||
cpu.set_register_pair(pair, value);
|
cpu.set_register_pair(pair, value);
|
||||||
}
|
}
|
||||||
|
@ -1015,34 +990,38 @@ impl Instruction {
|
||||||
if !flags.z() {
|
if !flags.z() {
|
||||||
Self::push(cpu, pc);
|
Self::push(cpu, pc);
|
||||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||||
return Cycles::new(24);
|
Cycles::new(24)
|
||||||
}
|
} else {
|
||||||
Cycles::new(12)
|
Cycles::new(12)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JumpCondition::Zero => {
|
JumpCondition::Zero => {
|
||||||
if flags.z() {
|
if flags.z() {
|
||||||
Self::push(cpu, pc);
|
Self::push(cpu, pc);
|
||||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||||
return Cycles::new(24);
|
Cycles::new(24)
|
||||||
}
|
} else {
|
||||||
Cycles::new(12)
|
Cycles::new(12)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JumpCondition::NotCarry => {
|
JumpCondition::NotCarry => {
|
||||||
if !flags.c() {
|
if !flags.c() {
|
||||||
Self::push(cpu, pc);
|
Self::push(cpu, pc);
|
||||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||||
return Cycles::new(24);
|
Cycles::new(24)
|
||||||
}
|
} else {
|
||||||
Cycles::new(12)
|
Cycles::new(12)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JumpCondition::Carry => {
|
JumpCondition::Carry => {
|
||||||
if flags.c() {
|
if flags.c() {
|
||||||
Self::push(cpu, pc);
|
Self::push(cpu, pc);
|
||||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||||
return Cycles::new(24);
|
Cycles::new(24)
|
||||||
}
|
} else {
|
||||||
Cycles::new(12)
|
Cycles::new(12)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JumpCondition::Always => {
|
JumpCondition::Always => {
|
||||||
Self::push(cpu, pc);
|
Self::push(cpu, pc);
|
||||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||||
|
@ -1072,328 +1051,255 @@ impl Instruction {
|
||||||
}
|
}
|
||||||
Instruction::RLC(reg) => {
|
Instruction::RLC(reg) => {
|
||||||
// RLC r[z] | Rotate register r[z] left
|
// RLC r[z] | Rotate register r[z] left
|
||||||
let mut flags: Flags = *cpu.flags();
|
use InstrRegister::*;
|
||||||
let msb;
|
|
||||||
let rot_reg;
|
|
||||||
let cycles: Cycles;
|
|
||||||
|
|
||||||
match reg {
|
let mut flags: Flags = *cpu.flags();
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
let (cycles, msb, rotated) = match reg {
|
||||||
| InstrRegister::D
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
|
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
msb = value >> 7;
|
let rotated = value.rotate_left(1);
|
||||||
rot_reg = value.rotate_left(1);
|
|
||||||
|
|
||||||
cpu.set_register(register, rot_reg);
|
cpu.set_register(register, rotated);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), value >> 7, rotated)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
|
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
msb = value >> 7;
|
let rotated = value.rotate_left(1);
|
||||||
rot_reg = value.rotate_left(1);
|
|
||||||
|
|
||||||
cpu.write_byte(addr, rot_reg);
|
cpu.write_byte(addr, rotated);
|
||||||
cycles = Cycles::new(16);
|
(Cycles::new(16), value >> 7, rotated)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(rot_reg == 0, false, false, msb == 0x01);
|
flags.update(rotated == 0, false, false, msb == 0x01);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
Instruction::RRC(reg) => {
|
Instruction::RRC(reg) => {
|
||||||
// RRC r[z] | Rotate Register r[z] right
|
// RRC r[z] | Rotate Register r[z] right
|
||||||
let mut flags: Flags = *cpu.flags();
|
use InstrRegister::*;
|
||||||
let lsb;
|
|
||||||
let rot_reg;
|
|
||||||
let cycles: Cycles;
|
|
||||||
|
|
||||||
match reg {
|
let mut flags: Flags = *cpu.flags();
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
let (cycles, lsb, rotated) = match reg {
|
||||||
| InstrRegister::D
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
|
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
lsb = value & 0x01;
|
let rotated = value.rotate_right(1);
|
||||||
rot_reg = value.rotate_right(1);
|
|
||||||
|
|
||||||
cpu.set_register(register, rot_reg);
|
cpu.set_register(register, rotated);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), value & 0x01, rotated)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
|
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
lsb = value & 0x01;
|
let rotated = value.rotate_right(1);
|
||||||
rot_reg = value.rotate_right(1);
|
|
||||||
|
|
||||||
cpu.write_byte(addr, rot_reg);
|
cpu.write_byte(addr, rotated);
|
||||||
cycles = Cycles::new(16);
|
(Cycles::new(16), value & 0x01, rotated)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(rot_reg == 0, false, false, lsb == 0x01);
|
flags.update(rotated == 0, false, false, lsb == 0x01);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
Instruction::RL(reg) => {
|
Instruction::RL(reg) => {
|
||||||
// RL r[z] | Rotate register r[z] left through carry
|
// RL r[z] | Rotate register r[z] left through carry
|
||||||
let mut flags: Flags = *cpu.flags();
|
use InstrRegister::*;
|
||||||
let carry;
|
|
||||||
let rot_reg;
|
|
||||||
let cycles: Cycles;
|
|
||||||
|
|
||||||
match reg {
|
let mut flags: Flags = *cpu.flags();
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
let (cycles, rotated, carry) = match reg {
|
||||||
| InstrRegister::D
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
let (new_reg, new_carry) = Self::rl_thru_carry(value, flags.c());
|
let (rotated, carry) = Self::rl_thru_carry(value, flags.c());
|
||||||
rot_reg = new_reg;
|
|
||||||
carry = new_carry;
|
|
||||||
|
|
||||||
cpu.set_register(register, rot_reg);
|
cpu.set_register(register, rotated);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), rotated, carry)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
let (new_reg, new_carry) = Self::rl_thru_carry(value, flags.c());
|
let (rotated, carry) = Self::rl_thru_carry(value, flags.c());
|
||||||
rot_reg = new_reg;
|
|
||||||
carry = new_carry;
|
|
||||||
|
|
||||||
cpu.write_byte(addr, rot_reg);
|
cpu.write_byte(addr, rotated);
|
||||||
cycles = Cycles::new(16);
|
(Cycles::new(16), rotated, carry)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(rot_reg == 0, false, false, carry);
|
flags.update(rotated == 0, false, false, carry);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
Instruction::RR(reg) => {
|
Instruction::RR(reg) => {
|
||||||
// RR r[z] | Rotate register r[z] right through carry
|
// RR r[z] | Rotate register r[z] right through carry
|
||||||
let mut flags: Flags = *cpu.flags();
|
use InstrRegister::*;
|
||||||
let carry;
|
|
||||||
let rot_reg;
|
|
||||||
let cycles: Cycles;
|
|
||||||
|
|
||||||
match reg {
|
let mut flags: Flags = *cpu.flags();
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
let (cycles, rotated, carry) = match reg {
|
||||||
| InstrRegister::D
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
let (new_reg, new_carry) = Self::rr_thru_carry(value, flags.c());
|
let (rotated, carry) = Self::rr_thru_carry(value, flags.c());
|
||||||
rot_reg = new_reg;
|
|
||||||
carry = new_carry;
|
|
||||||
|
|
||||||
cpu.set_register(register, rot_reg);
|
cpu.set_register(register, rotated);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), rotated, carry)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
let (new_reg, new_carry) = Self::rr_thru_carry(value, flags.c());
|
let (rotated, carry) = Self::rr_thru_carry(value, flags.c());
|
||||||
rot_reg = new_reg;
|
|
||||||
carry = new_carry;
|
|
||||||
|
|
||||||
cpu.write_byte(addr, rot_reg);
|
cpu.write_byte(addr, rotated);
|
||||||
cycles = Cycles::new(16);
|
(Cycles::new(16), rotated, carry)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(rot_reg == 0, false, false, carry);
|
flags.update(rotated == 0, false, false, carry);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
Instruction::SLA(reg) => {
|
Instruction::SLA(reg) => {
|
||||||
// SLA r[z] | Shift left arithmetic register r[z]
|
// SLA r[z] | Shift left arithmetic register r[z]
|
||||||
let mut flags: Flags = *cpu.flags();
|
use InstrRegister::*;
|
||||||
let shift_reg;
|
|
||||||
let msb;
|
|
||||||
let cycles: Cycles;
|
|
||||||
|
|
||||||
match reg {
|
let mut flags: Flags = *cpu.flags();
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
let (cycles, msb, shifted) = match reg {
|
||||||
| InstrRegister::D
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
msb = (value >> 7) & 0x01;
|
let shifted = value << 1;
|
||||||
shift_reg = value << 1;
|
|
||||||
|
|
||||||
cpu.set_register(register, shift_reg);
|
cpu.set_register(register, shifted);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), (value >> 7) & 0x01, shifted)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
msb = (value >> 7) & 0x01;
|
let shifted = value << 1;
|
||||||
shift_reg = value << 1;
|
|
||||||
|
|
||||||
cpu.write_byte(addr, value);
|
cpu.write_byte(addr, value);
|
||||||
cycles = Cycles::new(16);
|
(Cycles::new(16), (value >> 7) & 0x01, shifted)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(shift_reg == 0, false, false, msb == 0x01);
|
flags.update(shifted == 0, false, false, msb == 0x01);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
Instruction::SRA(reg) => {
|
Instruction::SRA(reg) => {
|
||||||
// SRA r[z] | Shift right arithmetic register r[z]
|
// SRA r[z] | Shift right arithmetic register r[z]
|
||||||
let mut flags: Flags = *cpu.flags();
|
use InstrRegister::*;
|
||||||
let shift_reg;
|
|
||||||
let lsb;
|
|
||||||
let cycles: Cycles;
|
|
||||||
|
|
||||||
match reg {
|
let mut flags: Flags = *cpu.flags();
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
let (cycles, lsb, shifted) = match reg {
|
||||||
| InstrRegister::D
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
lsb = value & 0x01;
|
|
||||||
let msb = (value >> 7) & 0x01;
|
let msb = (value >> 7) & 0x01;
|
||||||
shift_reg = (value >> 1) | (msb << 7); // msb is duplicated in this op
|
let shifted = msb << 7 | value >> 1;
|
||||||
|
|
||||||
cpu.set_register(register, shift_reg);
|
cpu.set_register(register, shifted);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), value & 0x01, shifted)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
lsb = value & 0x01;
|
|
||||||
let msb = (value >> 7) & 0x01;
|
let msb = (value >> 7) & 0x01;
|
||||||
shift_reg = (value >> 1) | (msb << 7); // msb is duplicated in this op
|
let shifted = msb << 7 | value >> 1;
|
||||||
|
|
||||||
cpu.write_byte(addr, value);
|
cpu.write_byte(addr, value);
|
||||||
cycles = Cycles::new(16);
|
(Cycles::new(16), value & 0x01, shifted)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(shift_reg == 0, false, false, lsb == 0x01);
|
flags.update(shifted == 0, false, false, lsb == 0x01);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
Instruction::SWAP(reg) => {
|
Instruction::SWAP(reg) => {
|
||||||
// SWAP r[z] | Swap the 4 highest and lowest bits in a byte
|
// SWAP r[z] | Swap the 4 highest and lowest bits in a byte
|
||||||
let mut flags: Flags = *cpu.flags();
|
use InstrRegister::*;
|
||||||
let swap_reg;
|
|
||||||
let cycles: Cycles;
|
|
||||||
|
|
||||||
match reg {
|
let mut flags: Flags = *cpu.flags();
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
let (cycles, swapped) = match reg {
|
||||||
| InstrRegister::D
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
swap_reg = Self::swap_bits(value);
|
let swapped = Self::swap_bits(value);
|
||||||
|
|
||||||
cpu.set_register(register, swap_reg);
|
cpu.set_register(register, swapped);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), swapped)
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
swap_reg = Self::swap_bits(value);
|
let swapped = Self::swap_bits(value);
|
||||||
|
|
||||||
cpu.write_byte(addr, swap_reg);
|
cpu.write_byte(addr, swapped);
|
||||||
cycles = Cycles::new(16)
|
(Cycles::new(16), swapped)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(swap_reg == 0, false, false, false);
|
flags.update(swapped == 0, false, false, false);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
|
||||||
cycles
|
cycles
|
||||||
}
|
}
|
||||||
Instruction::SRL(reg) => {
|
Instruction::SRL(reg) => {
|
||||||
// SRL r[z] | Shift right logic register r[z]
|
// SRL r[z] | Shift right logic register r[z]
|
||||||
let mut flags: Flags = *cpu.flags();
|
use InstrRegister::*;
|
||||||
let lsb;
|
|
||||||
let shift_reg;
|
|
||||||
let cycles: Cycles;
|
|
||||||
|
|
||||||
match reg {
|
let mut flags: Flags = *cpu.flags();
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
let (cycles, lsb, shift_reg) = match reg {
|
||||||
| InstrRegister::D
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
lsb = value & 0x01;
|
let shifted = value >> 1;
|
||||||
shift_reg = value >> 1;
|
|
||||||
|
|
||||||
cpu.set_register(register, shift_reg);
|
cpu.set_register(register, shifted);
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), value & 0x01, shifted)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
lsb = value & 0x01;
|
let shifted = value >> 1;
|
||||||
shift_reg = value >> 1;
|
|
||||||
|
|
||||||
cpu.write_byte(addr, shift_reg);
|
cpu.write_byte(addr, shifted);
|
||||||
cycles = Cycles::new(16);
|
(Cycles::new(16), value & 0x01, shifted)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(shift_reg == 0, false, false, lsb == 0x01);
|
flags.update(shift_reg == 0, false, false, lsb == 0x01);
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
@ -1402,31 +1308,26 @@ impl Instruction {
|
||||||
}
|
}
|
||||||
Instruction::BIT(y, reg) => {
|
Instruction::BIT(y, reg) => {
|
||||||
// BIT y, r[z] | Test y is in register r[z]
|
// BIT y, r[z] | Test y is in register r[z]
|
||||||
|
use InstrRegister::*;
|
||||||
|
|
||||||
let mut flags: Flags = *cpu.flags();
|
let mut flags: Flags = *cpu.flags();
|
||||||
let is_bit_set;
|
|
||||||
let cycles: Cycles;
|
let (cycles, is_bit_set) = match reg {
|
||||||
match reg {
|
B | C | D | E | H | L | A => {
|
||||||
InstrRegister::B
|
|
||||||
| InstrRegister::C
|
|
||||||
| InstrRegister::D
|
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
is_bit_set = ((value >> y) & 0x01) == 0x01;
|
let is_bit_set = ((value >> y) & 0x01) == 0x01;
|
||||||
cycles = Cycles::new(8);
|
(Cycles::new(8), is_bit_set)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
is_bit_set = ((value >> y) & 0x01) == 0x01;
|
let is_bit_set = ((value >> y) & 0x01) == 0x01;
|
||||||
cycles = Cycles::new(12);
|
(Cycles::new(12), is_bit_set)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
flags.update(!is_bit_set, false, true, flags.c());
|
flags.update(!is_bit_set, false, true, flags.c());
|
||||||
cpu.set_flags(flags);
|
cpu.set_flags(flags);
|
||||||
|
@ -1439,21 +1340,17 @@ impl Instruction {
|
||||||
// 00000001 << 3 = 00001000
|
// 00000001 << 3 = 00001000
|
||||||
// ~00001000 = 11110111
|
// ~00001000 = 11110111
|
||||||
// value & 11110111 means that only a specific bit will be reset
|
// value & 11110111 means that only a specific bit will be reset
|
||||||
|
use InstrRegister::*;
|
||||||
|
|
||||||
match reg {
|
match reg {
|
||||||
InstrRegister::B
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::C
|
|
||||||
| InstrRegister::D
|
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
cpu.set_register(register, value & !(1u8 << y));
|
cpu.set_register(register, value & !(1u8 << y));
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
|
@ -1467,21 +1364,17 @@ impl Instruction {
|
||||||
//
|
//
|
||||||
// 00000001 << 3 = 00001000
|
// 00000001 << 3 = 00001000
|
||||||
// value | 00001000 means that only a specific bit will be set
|
// value | 00001000 means that only a specific bit will be set
|
||||||
|
use InstrRegister::*;
|
||||||
|
|
||||||
match reg {
|
match reg {
|
||||||
InstrRegister::B
|
B | C | D | E | H | L | A => {
|
||||||
| InstrRegister::C
|
|
||||||
| InstrRegister::D
|
|
||||||
| InstrRegister::E
|
|
||||||
| InstrRegister::H
|
|
||||||
| InstrRegister::L
|
|
||||||
| InstrRegister::A => {
|
|
||||||
let register = reg.to_register();
|
let register = reg.to_register();
|
||||||
let value = cpu.register(register);
|
let value = cpu.register(register);
|
||||||
|
|
||||||
cpu.set_register(register, value | (1u8 << y));
|
cpu.set_register(register, value | (1u8 << y));
|
||||||
Cycles::new(8)
|
Cycles::new(8)
|
||||||
}
|
}
|
||||||
InstrRegister::IndirectHL => {
|
IndirectHL => {
|
||||||
let addr = cpu.register_pair(RegisterPair::HL);
|
let addr = cpu.register_pair(RegisterPair::HL);
|
||||||
let value = cpu.read_byte(addr);
|
let value = cpu.read_byte(addr);
|
||||||
|
|
||||||
|
@ -1559,12 +1452,9 @@ impl Instruction {
|
||||||
fn add_u16_i8(left: u16, right: i8, flags: &mut Flags) -> u16 {
|
fn add_u16_i8(left: u16, right: i8, flags: &mut Flags) -> u16 {
|
||||||
let (sum, did_overflow) = left.overflowing_add(right as u16);
|
let (sum, did_overflow) = left.overflowing_add(right as u16);
|
||||||
|
|
||||||
flags.update(
|
// FIXME: Is this more correct?
|
||||||
false,
|
let half_carry = Self::add_u8_half_carry((left >> 8) as u8, right as u8);
|
||||||
false,
|
flags.update(false, false, half_carry, did_overflow);
|
||||||
Self::add_u16_half_carry(left, right as u16),
|
|
||||||
did_overflow,
|
|
||||||
);
|
|
||||||
sum
|
sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1623,7 +1513,7 @@ impl Instruction {
|
||||||
|
|
||||||
fn rr_thru_carry(byte: u8, carry: bool) -> (u8, bool) {
|
fn rr_thru_carry(byte: u8, carry: bool) -> (u8, bool) {
|
||||||
let carry_flag = byte & 0x01; // get the LSB of the u8 (which will rotate into the carry bit)
|
let carry_flag = byte & 0x01; // get the LSB of the u8 (which will rotate into the carry bit)
|
||||||
let new_byte = (byte >> 1) | ((carry as u8) << 7); // shift the bit right, and then OR the carry bit in.
|
let new_byte = ((carry as u8) << 7) | (byte >> 1); // shift the bit right, and then OR the carry bit in.
|
||||||
|
|
||||||
(new_byte, carry_flag == 0x01)
|
(new_byte, carry_flag == 0x01)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue