Compare commits

..

2 Commits

Author SHA1 Message Date
Rekai Nyangadzayi Musuka 4516ca8477 chore: run cargo fix
continuous-integration/drone/push Build is passing Details
2021-09-12 04:56:39 -03:00
Rekai Nyangadzayi Musuka 6087e3b20b chore: remove Cycle struct and begin scheduler design 2021-09-12 04:56:34 -03:00
1 changed files with 91 additions and 91 deletions

View File

@ -123,7 +123,7 @@ impl Instruction {
let addr = Self::imm_word(cpu); let addr = Self::imm_word(cpu);
let sp = cpu.register_pair(RegisterPair::SP); let sp = cpu.register_pair(RegisterPair::SP);
Self::write_word(&mut cpu.bus, addr, sp); Self::write_word(&mut cpu.bus, addr, sp);
(20) 20
} }
(LDTarget::Group1(pair), LDSource::ImmediateWord) => { (LDTarget::Group1(pair), LDSource::ImmediateWord) => {
// LD r16, u16 | Store u16 in 16-bit register // LD r16, u16 | Store u16 in 16-bit register
@ -133,7 +133,7 @@ impl Instruction {
match pair { match pair {
BC | DE | HL | SP => cpu.set_register_pair(pair.as_register_pair(), word), BC | DE | HL | SP => cpu.set_register_pair(pair.as_register_pair(), word),
} }
(12) 12
} }
(LDTarget::IndirectGroup2(pair), LDSource::A) => { (LDTarget::IndirectGroup2(pair), LDSource::A) => {
// LD (r16), A | Store accumulator in byte at 16-bit register // LD (r16), A | Store accumulator in byte at 16-bit register
@ -155,7 +155,7 @@ impl Instruction {
cpu.set_register_pair(RegisterPair::HL, addr - 1); cpu.set_register_pair(RegisterPair::HL, addr - 1);
} }
} }
(8) 8
} }
(LDTarget::A, LDSource::IndirectGroup2(pair)) => { (LDTarget::A, LDSource::IndirectGroup2(pair)) => {
// LD A, (r16) | Store byte at 16-bit register in accumulator // LD A, (r16) | Store byte at 16-bit register in accumulator
@ -178,7 +178,7 @@ impl Instruction {
cpu.set_register_pair(RegisterPair::HL, addr - 1); cpu.set_register_pair(RegisterPair::HL, addr - 1);
} }
} }
(8) 8
} }
(LDTarget::Register(reg), LDSource::ImmediateByte) => { (LDTarget::Register(reg), LDSource::ImmediateByte) => {
// LD r8, u8 | Store u8 in 8-bit register // LD r8, u8 | Store u8 in 8-bit register
@ -188,12 +188,12 @@ impl Instruction {
match reg { match reg {
A | B | C | D | E | H | L => { A | B | C | D | E | H | L => {
cpu.set_register(reg.cpu_register(), right); cpu.set_register(reg.cpu_register(), right);
(8) 8
} }
IndirectHL => { IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
Self::write_byte(&mut cpu.bus, addr, right); Self::write_byte(&mut cpu.bus, addr, right);
(12) 12
} }
} }
} }
@ -202,14 +202,14 @@ impl Instruction {
let addr = 0xFF00 + cpu.register(CpuRegister::C) as u16; let addr = 0xFF00 + cpu.register(CpuRegister::C) as u16;
let acc = cpu.register(CpuRegister::A); let acc = cpu.register(CpuRegister::A);
Self::write_byte(&mut cpu.bus, addr, acc); Self::write_byte(&mut cpu.bus, addr, acc);
(8) 8
} }
(LDTarget::A, LDSource::IoWithC) => { (LDTarget::A, LDSource::IoWithC) => {
// LD A, (0xFF00 + C) | Store byte at 0xFF00 + C in register A // LD A, (0xFF00 + C) | Store byte at 0xFF00 + C in register A
let addr = 0xFF00 + cpu.register(CpuRegister::C) as u16; let addr = 0xFF00 + cpu.register(CpuRegister::C) as u16;
let byte = Self::read_byte(&mut cpu.bus, addr); let byte = Self::read_byte(&mut cpu.bus, addr);
cpu.set_register(CpuRegister::A, byte); cpu.set_register(CpuRegister::A, byte);
(8) 8
} }
(LDTarget::Register(target), LDSource::Register(source)) => { (LDTarget::Register(target), LDSource::Register(source)) => {
// LD r8, r8 | Store 8-bit register in 8-bit register // LD r8, r8 | Store 8-bit register in 8-bit register
@ -222,12 +222,12 @@ impl Instruction {
match target { match target {
B | C | D | E | H | L | A => { B | C | D | E | H | L | A => {
cpu.set_register(target.cpu_register(), right); cpu.set_register(target.cpu_register(), right);
(4) 4
} }
IndirectHL => { IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
Self::write_byte(&mut cpu.bus, addr, right); Self::write_byte(&mut cpu.bus, addr, right);
(8) 8
} }
} }
} }
@ -238,7 +238,7 @@ impl Instruction {
match target { match target {
B | C | D | E | H | L | A => { B | C | D | E | H | L | A => {
cpu.set_register(target.cpu_register(), right); cpu.set_register(target.cpu_register(), right);
(8) 8
} }
IndirectHL => { IndirectHL => {
unreachable!("LD (HL), (HL) is an illegal instruction") unreachable!("LD (HL), (HL) is an illegal instruction")
@ -252,33 +252,33 @@ impl Instruction {
let addr = 0xFF00 + Self::imm_byte(cpu) as u16; let addr = 0xFF00 + Self::imm_byte(cpu) as u16;
let acc = cpu.register(CpuRegister::A); let acc = cpu.register(CpuRegister::A);
Self::write_byte(&mut cpu.bus, addr, acc); Self::write_byte(&mut cpu.bus, addr, acc);
(12) 12
} }
(LDTarget::A, LDSource::IoWithImmediateOffset) => { (LDTarget::A, LDSource::IoWithImmediateOffset) => {
// LD A, (0xFF00 + u8) | Store byte at address 0xFF00 + u8 in accumulator // LD A, (0xFF00 + u8) | Store byte at address 0xFF00 + u8 in accumulator
let addr = 0xFF00 + Self::imm_byte(cpu) as u16; let addr = 0xFF00 + Self::imm_byte(cpu) as u16;
let byte = Self::read_byte(&mut cpu.bus, addr); let byte = Self::read_byte(&mut cpu.bus, addr);
cpu.set_register(CpuRegister::A, byte); cpu.set_register(CpuRegister::A, byte);
(12) 12
} }
(LDTarget::SP, LDSource::HL) => { (LDTarget::SP, LDSource::HL) => {
// LD SP, HL | Store HL in stack pointer // LD SP, HL | Store HL in stack pointer
cpu.set_register_pair(RegisterPair::SP, cpu.register_pair(RegisterPair::HL)); cpu.set_register_pair(RegisterPair::SP, cpu.register_pair(RegisterPair::HL));
(8) // performs an internal operation that takes 4 cycles 8 // performs an internal operation that takes 4 cycles
} }
(LDTarget::IndirectImmediateWord, LDSource::A) => { (LDTarget::IndirectImmediateWord, LDSource::A) => {
// LD (u16), A | Store accumulator in byte at 16-bit register // LD (u16), A | Store accumulator in byte at 16-bit register
let addr = Self::imm_word(cpu); let addr = Self::imm_word(cpu);
let acc = cpu.register(CpuRegister::A); let acc = cpu.register(CpuRegister::A);
Self::write_byte(&mut cpu.bus, addr, acc); Self::write_byte(&mut cpu.bus, addr, acc);
(16) 16
} }
(LDTarget::A, LDSource::IndirectImmediateWord) => { (LDTarget::A, LDSource::IndirectImmediateWord) => {
// LD A, (u16) | Store byte at 16-bit register in accumulator // LD A, (u16) | Store byte at 16-bit register in accumulator
let addr = Self::imm_word(cpu); let addr = Self::imm_word(cpu);
let byte = Self::read_byte(&mut cpu.bus, addr); let byte = Self::read_byte(&mut cpu.bus, addr);
cpu.set_register(CpuRegister::A, byte); cpu.set_register(CpuRegister::A, byte);
(16) 16
} }
_ => unreachable!("LD {:?}, {:?} is an illegal instruction", target, src), _ => unreachable!("LD {:?}, {:?} is an illegal instruction", target, src),
}, },
@ -296,38 +296,38 @@ impl Instruction {
JumpCondition::NotZero => { JumpCondition::NotZero => {
if !flags.z() { if !flags.z() {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(12) 12
} else { } else {
(8) 8
} }
} }
JumpCondition::Zero => { JumpCondition::Zero => {
if flags.z() { if flags.z() {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(12) 12
} else { } else {
(8) 8
} }
} }
JumpCondition::NotCarry => { JumpCondition::NotCarry => {
if !flags.c() { if !flags.c() {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(12) 12
} else { } else {
(8) 8
} }
} }
JumpCondition::Carry => { JumpCondition::Carry => {
if flags.c() { if flags.c() {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(12) 12
} else { } else {
(8) 8
} }
} }
JumpCondition::Always => { JumpCondition::Always => {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(12) 12
} }
} }
} }
@ -349,7 +349,7 @@ impl Instruction {
} }
} }
cpu.set_flags(flags); cpu.set_flags(flags);
(8) 8
} }
(AddTarget::A, AddSource::Register(reg)) => { (AddTarget::A, AddSource::Register(reg)) => {
// ADD A, r8 | Add 8-bit register to accumulator // ADD A, r8 | Add 8-bit register to accumulator
@ -383,7 +383,7 @@ impl Instruction {
let sum = Self::add_u16_i8(left, Self::imm_byte(cpu) as i8, &mut flags); let sum = Self::add_u16_i8(left, Self::imm_byte(cpu) as i8, &mut flags);
cpu.set_register_pair(RegisterPair::SP, sum); cpu.set_register_pair(RegisterPair::SP, sum);
cpu.set_flags(flags); cpu.set_flags(flags);
(16) 16
} }
(AddTarget::A, AddSource::ImmediateByte) => { (AddTarget::A, AddSource::ImmediateByte) => {
// ADD A, u8 | Add u8 to accumulator // ADD A, u8 | Add u8 to accumulator
@ -393,7 +393,7 @@ impl Instruction {
let sum = Self::add(left, Self::imm_byte(cpu), &mut flags); let sum = Self::add(left, Self::imm_byte(cpu), &mut flags);
cpu.set_register(CpuRegister::A, sum); cpu.set_register(CpuRegister::A, sum);
cpu.set_flags(flags); cpu.set_flags(flags);
(8) 8
} }
_ => unreachable!("ADD {:?}, {:?} is an illegal instruction", target, src), _ => unreachable!("ADD {:?}, {:?} is an illegal instruction", target, src),
}, },
@ -408,13 +408,13 @@ impl Instruction {
B | C | D | E | H | L | A => { B | C | D | E | H | L | A => {
let reg = reg.cpu_register(); let reg = reg.cpu_register();
cpu.set_register(reg, Self::inc(cpu.register(reg), &mut flags)); cpu.set_register(reg, Self::inc(cpu.register(reg), &mut flags));
(4) 4
} }
IndirectHL => { IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
let left = Self::read_byte(&mut cpu.bus, addr); let left = Self::read_byte(&mut cpu.bus, addr);
Self::write_byte(&mut cpu.bus, addr, Self::inc(left, &mut flags)); Self::write_byte(&mut cpu.bus, addr, Self::inc(left, &mut flags));
(12) 12
} }
}; };
cpu.set_flags(flags); cpu.set_flags(flags);
@ -433,7 +433,7 @@ impl Instruction {
cpu.set_register_pair(pair, left.wrapping_add(1)); cpu.set_register_pair(pair, left.wrapping_add(1));
} }
} }
(8) 8
} }
} }
} }
@ -448,13 +448,13 @@ impl Instruction {
B | C | D | E | H | L | A => { B | C | D | E | H | L | A => {
let reg = reg.cpu_register(); let reg = reg.cpu_register();
cpu.set_register(reg, Self::dec(cpu.register(reg), &mut flags)); cpu.set_register(reg, Self::dec(cpu.register(reg), &mut flags));
(4) 4
} }
IndirectHL => { IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
let left = Self::read_byte(&mut cpu.bus, addr); let left = Self::read_byte(&mut cpu.bus, addr);
Self::write_byte(&mut cpu.bus, addr, Self::dec(left, &mut flags)); Self::write_byte(&mut cpu.bus, addr, Self::dec(left, &mut flags));
(12) 12
} }
}; };
cpu.set_flags(flags); cpu.set_flags(flags);
@ -472,7 +472,7 @@ impl Instruction {
cpu.set_register_pair(pair, left.wrapping_sub(1)); cpu.set_register_pair(pair, left.wrapping_sub(1));
} }
}; };
(8) 8
} }
} }
} }
@ -483,7 +483,7 @@ impl Instruction {
let acc_rotated = acc.rotate_left(1); let acc_rotated = acc.rotate_left(1);
cpu.set_register(CpuRegister::A, acc_rotated); cpu.set_register(CpuRegister::A, acc_rotated);
cpu.update_flags(false, false, false, most_sgfnt == 0x01); cpu.update_flags(false, false, false, most_sgfnt == 0x01);
(4) 4
} }
Instruction::RRCA => { Instruction::RRCA => {
// RRCA | Rotate accumulator right // RRCA | Rotate accumulator right
@ -492,7 +492,7 @@ impl Instruction {
let acc_rotated = acc.rotate_right(1); let acc_rotated = acc.rotate_right(1);
cpu.set_register(CpuRegister::A, acc_rotated); cpu.set_register(CpuRegister::A, acc_rotated);
cpu.update_flags(false, false, false, least_sgfnt == 0x01); cpu.update_flags(false, false, false, least_sgfnt == 0x01);
(4) 4
} }
Instruction::RLA => { Instruction::RLA => {
// RLA | Rotate accumulator left through carry // RLA | Rotate accumulator left through carry
@ -502,7 +502,7 @@ impl Instruction {
let (acc_rotated, carry) = Self::rl_thru_carry(acc, flags.c()); let (acc_rotated, carry) = Self::rl_thru_carry(acc, flags.c());
cpu.set_register(CpuRegister::A, acc_rotated); cpu.set_register(CpuRegister::A, acc_rotated);
cpu.update_flags(false, false, false, carry); cpu.update_flags(false, false, false, carry);
(4) 4
} }
Instruction::RRA => { Instruction::RRA => {
// RRA | Rotate accumulator right through carry // RRA | Rotate accumulator right through carry
@ -512,7 +512,7 @@ impl Instruction {
let (acc_rotated, carry) = Self::rr_thru_carry(acc, flags.c()); let (acc_rotated, carry) = Self::rr_thru_carry(acc, flags.c());
cpu.set_register(CpuRegister::A, acc_rotated); cpu.set_register(CpuRegister::A, acc_rotated);
cpu.update_flags(false, false, false, carry); cpu.update_flags(false, false, false, carry);
(4) 4
} }
Instruction::DAA => { Instruction::DAA => {
// DAA | Change accumulator into its BCD representation // DAA | Change accumulator into its BCD representation
@ -553,7 +553,7 @@ impl Instruction {
flags.set_z(tmp as u8 == 0); flags.set_z(tmp as u8 == 0);
flags.set_h(false); flags.set_h(false);
cpu.set_flags(flags); cpu.set_flags(flags);
(4) 4
} }
Instruction::CPL => { Instruction::CPL => {
// CPL | Compliment accumulator // CPL | Compliment accumulator
@ -564,7 +564,7 @@ impl Instruction {
flags.set_n(true); flags.set_n(true);
flags.set_h(true); flags.set_h(true);
cpu.set_flags(flags); cpu.set_flags(flags);
(4) 4
} }
Instruction::SCF => { Instruction::SCF => {
// SCF | Set Carry Flag // SCF | Set Carry Flag
@ -574,7 +574,7 @@ impl Instruction {
flags.set_h(false); flags.set_h(false);
flags.set_c(true); flags.set_c(true);
cpu.set_flags(flags); cpu.set_flags(flags);
(4) 4
} }
Instruction::CCF => { Instruction::CCF => {
// CCF | Compliment Carry Flag // CCF | Compliment Carry Flag
@ -584,7 +584,7 @@ impl Instruction {
flags.set_h(false); flags.set_h(false);
flags.set_c(!flags.c()); flags.set_c(!flags.c());
cpu.set_flags(flags); cpu.set_flags(flags);
(4) 4
} }
Instruction::HALT => { Instruction::HALT => {
// HALT | Enter CPU low power consumption mode until interrupt occurs // HALT | Enter CPU low power consumption mode until interrupt occurs
@ -596,7 +596,7 @@ impl Instruction {
_ => NonePending, _ => NonePending,
}; };
cpu.halt_cpu(kind); cpu.halt_cpu(kind);
(4) 4
} }
Instruction::ADC(source) => match source { Instruction::ADC(source) => match source {
AluSource::Register(reg) => { AluSource::Register(reg) => {
@ -632,7 +632,7 @@ impl Instruction {
let sum = Self::add_with_carry_bit(left, right, flags.c(), &mut flags); let sum = Self::add_with_carry_bit(left, right, flags.c(), &mut flags);
cpu.set_register(CpuRegister::A, sum); cpu.set_register(CpuRegister::A, sum);
cpu.set_flags(flags); cpu.set_flags(flags);
(8) 8
} }
}, },
Instruction::SUB(source) => match source { Instruction::SUB(source) => match source {
@ -666,7 +666,7 @@ impl Instruction {
let right = Self::imm_byte(cpu); let right = Self::imm_byte(cpu);
cpu.set_register(CpuRegister::A, Self::sub(left, right, &mut flags)); cpu.set_register(CpuRegister::A, Self::sub(left, right, &mut flags));
cpu.set_flags(flags); cpu.set_flags(flags);
(8) 8
} }
}, },
Instruction::SBC(target) => match target { Instruction::SBC(target) => match target {
@ -703,7 +703,7 @@ impl Instruction {
let diff = Self::sub_with_carry(left, right, flags.c(), &mut flags); let diff = Self::sub_with_carry(left, right, flags.c(), &mut flags);
cpu.set_register(CpuRegister::A, diff); cpu.set_register(CpuRegister::A, diff);
cpu.set_flags(flags); cpu.set_flags(flags);
(8) 8
} }
}, },
Instruction::AND(target) => match target { Instruction::AND(target) => match target {
@ -729,7 +729,7 @@ impl Instruction {
let acc = cpu.register(CpuRegister::A) & Self::imm_byte(cpu); let acc = cpu.register(CpuRegister::A) & Self::imm_byte(cpu);
cpu.set_register(CpuRegister::A, acc); cpu.set_register(CpuRegister::A, acc);
cpu.update_flags(acc == 0, false, true, false); cpu.update_flags(acc == 0, false, true, false);
(8) 8
} }
}, },
Instruction::XOR(source) => match source { Instruction::XOR(source) => match source {
@ -755,7 +755,7 @@ impl Instruction {
let acc = cpu.register(CpuRegister::A) ^ Self::imm_byte(cpu); let acc = cpu.register(CpuRegister::A) ^ Self::imm_byte(cpu);
cpu.set_register(CpuRegister::A, acc); cpu.set_register(CpuRegister::A, acc);
cpu.update_flags(acc == 0, false, false, false); cpu.update_flags(acc == 0, false, false, false);
(8) 8
} }
}, },
Instruction::OR(target) => match target { Instruction::OR(target) => match target {
@ -781,7 +781,7 @@ impl Instruction {
let acc = cpu.register(CpuRegister::A) | Self::imm_byte(cpu); let acc = cpu.register(CpuRegister::A) | Self::imm_byte(cpu);
cpu.set_register(CpuRegister::A, acc); cpu.set_register(CpuRegister::A, acc);
cpu.update_flags(acc == 0, false, false, false); cpu.update_flags(acc == 0, false, false, false);
(8) 8
} }
}, },
Instruction::CP(target) => match target { Instruction::CP(target) => match target {
@ -795,13 +795,13 @@ impl Instruction {
let cycles = match reg { let cycles = match reg {
B | C | D | E | H | L | A => { B | C | D | E | H | L | A => {
let _ = Self::sub(left, cpu.register(reg.cpu_register()), &mut flags); let _ = Self::sub(left, cpu.register(reg.cpu_register()), &mut flags);
(4) 4
} }
IndirectHL => { IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
let right = Self::read_byte(&mut cpu.bus, addr); let right = Self::read_byte(&mut cpu.bus, addr);
let _ = Self::sub(left, right, &mut flags); let _ = Self::sub(left, right, &mut flags);
(8) 8
} }
}; };
cpu.set_flags(flags); cpu.set_flags(flags);
@ -814,7 +814,7 @@ impl Instruction {
let left = cpu.register(CpuRegister::A); let left = cpu.register(CpuRegister::A);
let _ = Self::sub(left, Self::imm_byte(cpu), &mut flags); let _ = Self::sub(left, Self::imm_byte(cpu), &mut flags);
cpu.set_flags(flags); cpu.set_flags(flags);
(8) 8
} }
}, },
Instruction::LDHL => { Instruction::LDHL => {
@ -826,7 +826,7 @@ impl Instruction {
cpu.set_register_pair(RegisterPair::HL, sum); cpu.set_register_pair(RegisterPair::HL, sum);
cpu.set_flags(flags); cpu.set_flags(flags);
cpu.bus.clock(); // FIXME: Is this in the right place? cpu.bus.clock(); // FIXME: Is this in the right place?
(12) 12
} }
Instruction::RET(cond) => { Instruction::RET(cond) => {
// RET cond | Return from subroutine if condition is true // RET cond | Return from subroutine if condition is true
@ -840,9 +840,9 @@ impl Instruction {
if !flags.z() { if !flags.z() {
let addr = Self::pop(cpu); let addr = Self::pop(cpu);
Self::jump(cpu, addr); Self::jump(cpu, addr);
(20) 20
} else { } else {
(8) 8
} }
} }
JumpCondition::Zero => { JumpCondition::Zero => {
@ -851,9 +851,9 @@ impl Instruction {
if flags.z() { if flags.z() {
let addr = Self::pop(cpu); let addr = Self::pop(cpu);
Self::jump(cpu, addr); Self::jump(cpu, addr);
(20) 20
} else { } else {
(8) 8
} }
} }
JumpCondition::NotCarry => { JumpCondition::NotCarry => {
@ -862,9 +862,9 @@ impl Instruction {
if !flags.c() { if !flags.c() {
let addr = Self::pop(cpu); let addr = Self::pop(cpu);
Self::jump(cpu, addr); Self::jump(cpu, addr);
(20) 20
} else { } else {
(8) 8
} }
} }
JumpCondition::Carry => { JumpCondition::Carry => {
@ -873,15 +873,15 @@ impl Instruction {
if flags.c() { if flags.c() {
let addr = Self::pop(cpu); let addr = Self::pop(cpu);
Self::jump(cpu, addr); Self::jump(cpu, addr);
(20) 20
} else { } else {
(8) 8
} }
} }
JumpCondition::Always => { JumpCondition::Always => {
let addr = Self::pop(cpu); let addr = Self::pop(cpu);
Self::jump(cpu, addr); Self::jump(cpu, addr);
(16) 16
} }
} }
} }
@ -895,21 +895,21 @@ impl Instruction {
cpu.set_register_pair(pair.as_register_pair(), right); cpu.set_register_pair(pair.as_register_pair(), right);
} }
} }
(12) 12
} }
Instruction::RETI => { Instruction::RETI => {
// RETI | Return from subroutine, then enable interrupts // RETI | Return from subroutine, then enable interrupts
let addr = Self::pop(cpu); let addr = Self::pop(cpu);
Self::jump(cpu, addr); Self::jump(cpu, addr);
cpu.set_ime(ImeState::Enabled); cpu.set_ime(ImeState::Enabled);
(16) 16
} }
Instruction::JP(cond, location) => match location { Instruction::JP(cond, location) => match location {
JumpLocation::HL => { JumpLocation::HL => {
// JP HL | Store HL in program counter // JP HL | Store HL in program counter
let right = cpu.register_pair(RegisterPair::HL); let right = cpu.register_pair(RegisterPair::HL);
cpu.set_register_pair(RegisterPair::PC, right); cpu.set_register_pair(RegisterPair::PC, right);
(4) 4
} }
JumpLocation::ImmediateWord => { JumpLocation::ImmediateWord => {
// JP cond u16 | Store u16 in program counter if condition is true // JP cond u16 | Store u16 in program counter if condition is true
@ -922,38 +922,38 @@ impl Instruction {
JumpCondition::NotZero => { JumpCondition::NotZero => {
if !flags.z() { if !flags.z() {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(16) 16
} else { } else {
(12) 12
} }
} }
JumpCondition::Zero => { JumpCondition::Zero => {
if flags.z() { if flags.z() {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(16) 16
} else { } else {
(12) 12
} }
} }
JumpCondition::NotCarry => { JumpCondition::NotCarry => {
if !flags.c() { if !flags.c() {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(16) 16
} else { } else {
(12) 12
} }
} }
JumpCondition::Carry => { JumpCondition::Carry => {
if flags.c() { if flags.c() {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(16) 16
} else { } else {
(12) 12
} }
} }
JumpCondition::Always => { JumpCondition::Always => {
Self::jump(cpu, addr); Self::jump(cpu, addr);
(16) 16
} }
} }
} }
@ -961,12 +961,12 @@ impl Instruction {
Instruction::DI => { Instruction::DI => {
// DI | Disable IME // DI | Disable IME
cpu.set_ime(ImeState::Disabled); cpu.set_ime(ImeState::Disabled);
(4) 4
} }
Instruction::EI => { Instruction::EI => {
// EI | Enable IME after the next instruction // EI | Enable IME after the next instruction
cpu.set_ime(ImeState::EiExecuted); cpu.set_ime(ImeState::EiExecuted);
(4) 4
} }
Instruction::CALL(cond) => { Instruction::CALL(cond) => {
// CALL cond u16 | Push PC on the stack and store u16 in program counter if condition is true // CALL cond u16 | Push PC on the stack and store u16 in program counter if condition is true
@ -982,9 +982,9 @@ impl Instruction {
cpu.bus.clock(); // internal branch decision cpu.bus.clock(); // internal branch decision
Self::push(cpu, return_addr); Self::push(cpu, return_addr);
cpu.set_register_pair(RegisterPair::PC, addr); cpu.set_register_pair(RegisterPair::PC, addr);
(24) 24
} else { } else {
(12) 12
} }
} }
JumpCondition::Zero => { JumpCondition::Zero => {
@ -992,9 +992,9 @@ impl Instruction {
cpu.bus.clock(); // internal branch decision cpu.bus.clock(); // internal branch decision
Self::push(cpu, return_addr); Self::push(cpu, return_addr);
cpu.set_register_pair(RegisterPair::PC, addr); cpu.set_register_pair(RegisterPair::PC, addr);
(24) 24
} else { } else {
(12) 12
} }
} }
JumpCondition::NotCarry => { JumpCondition::NotCarry => {
@ -1002,9 +1002,9 @@ impl Instruction {
cpu.bus.clock(); // internal branch decision cpu.bus.clock(); // internal branch decision
Self::push(cpu, return_addr); Self::push(cpu, return_addr);
cpu.set_register_pair(RegisterPair::PC, addr); cpu.set_register_pair(RegisterPair::PC, addr);
(24) 24
} else { } else {
(12) 12
} }
} }
JumpCondition::Carry => { JumpCondition::Carry => {
@ -1012,16 +1012,16 @@ impl Instruction {
cpu.bus.clock(); // internal branch decision cpu.bus.clock(); // internal branch decision
Self::push(cpu, return_addr); Self::push(cpu, return_addr);
cpu.set_register_pair(RegisterPair::PC, addr); cpu.set_register_pair(RegisterPair::PC, addr);
(24) 24
} else { } else {
(12) 12
} }
} }
JumpCondition::Always => { JumpCondition::Always => {
cpu.bus.clock(); // internal branch decision cpu.bus.clock(); // internal branch decision
Self::push(cpu, return_addr); Self::push(cpu, return_addr);
cpu.set_register_pair(RegisterPair::PC, addr); cpu.set_register_pair(RegisterPair::PC, addr);
(24) 24
} }
} }
} }
@ -1037,7 +1037,7 @@ impl Instruction {
Self::push(cpu, word); Self::push(cpu, word);
} }
} }
(16) 16
} }
Instruction::RST(vector) => { Instruction::RST(vector) => {
// RST vector | Push current address onto the stack, jump to 0x0000 + n // RST vector | Push current address onto the stack, jump to 0x0000 + n
@ -1262,13 +1262,13 @@ impl Instruction {
let register = reg.cpu_register(); let register = reg.cpu_register();
let byte = cpu.register(register); let byte = cpu.register(register);
cpu.set_register(register, byte & !(1 << bit)); cpu.set_register(register, byte & !(1 << bit));
(8) 8
} }
IndirectHL => { IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr); let byte = Self::read_byte(&mut cpu.bus, addr);
Self::write_byte(&mut cpu.bus, addr, byte & !(1 << bit)); Self::write_byte(&mut cpu.bus, addr, byte & !(1 << bit));
(16) 16
} }
} }
} }
@ -1281,13 +1281,13 @@ impl Instruction {
let reg = reg.cpu_register(); let reg = reg.cpu_register();
let byte = cpu.register(reg); let byte = cpu.register(reg);
cpu.set_register(reg, byte | (1u8 << bit)); cpu.set_register(reg, byte | (1u8 << bit));
(8) 8
} }
IndirectHL => { IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr); let byte = Self::read_byte(&mut cpu.bus, addr);
Self::write_byte(&mut cpu.bus, addr, byte | (1u8 << bit)); Self::write_byte(&mut cpu.bus, addr, byte | (1u8 << bit));
(16) 16
} }
} }
} }
@ -1473,7 +1473,7 @@ impl Instruction {
let addr = cpu.register_pair(RegisterPair::PC); let addr = cpu.register_pair(RegisterPair::PC);
Self::push(cpu, addr); Self::push(cpu, addr);
cpu.set_register_pair(RegisterPair::PC, vector as u16); cpu.set_register_pair(RegisterPair::PC, vector as u16);
(16) 16
} }
/// Read u8 from memory (4 cycles) /// Read u8 from memory (4 cycles)