Skip to content
Snippets Groups Projects
inst.rs 62.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • fn set_4_l(cpu: &mut Cpu) {
        cpu.l = set(cpu.l, 4);
    }
    
    fn set_4_mhl(cpu: &mut Cpu) {
        let hl = cpu.hl();
        let byte = cpu.mmu.read(hl);
        let value = set(byte, 4);
        cpu.mmu.write(hl, value);
    }
    
    
    fn set_4_a(cpu: &mut Cpu) {
        cpu.a = set(cpu.a, 4);
    }
    
    
    fn set_5_b(cpu: &mut Cpu) {
        cpu.b = set(cpu.b, 5);
    }
    
    fn set_5_c(cpu: &mut Cpu) {
        cpu.c = set(cpu.c, 5);
    }
    
    fn set_5_d(cpu: &mut Cpu) {
        cpu.d = set(cpu.d, 5);
    }
    
    fn set_5_e(cpu: &mut Cpu) {
        cpu.e = set(cpu.e, 5);
    }
    
    fn set_5_h(cpu: &mut Cpu) {
        cpu.h = set(cpu.h, 5);
    }
    
    fn set_5_l(cpu: &mut Cpu) {
        cpu.l = set(cpu.l, 5);
    }
    
    fn set_5_mhl(cpu: &mut Cpu) {
        let hl = cpu.hl();
        let byte = cpu.mmu.read(hl);
        let value = set(byte, 5);
        cpu.mmu.write(hl, value);
    }
    
    fn set_5_a(cpu: &mut Cpu) {
        cpu.a = set(cpu.a, 5);
    }
    
    fn set_6_b(cpu: &mut Cpu) {
        cpu.b = set(cpu.b, 6);
    }
    
    fn set_6_c(cpu: &mut Cpu) {
        cpu.c = set(cpu.c, 6);
    }
    
    fn set_6_d(cpu: &mut Cpu) {
        cpu.d = set(cpu.d, 6);
    }
    
    fn set_6_e(cpu: &mut Cpu) {
        cpu.e = set(cpu.e, 6);
    }
    
    fn set_6_h(cpu: &mut Cpu) {
        cpu.h = set(cpu.h, 6);
    }
    
    fn set_6_l(cpu: &mut Cpu) {
        cpu.l = set(cpu.l, 6);
    }
    
    fn set_6_mhl(cpu: &mut Cpu) {
        let hl = cpu.hl();
        let byte = cpu.mmu.read(hl);
        let value = set(byte, 6);
        cpu.mmu.write(hl, value);
    }
    
    fn set_6_a(cpu: &mut Cpu) {
        cpu.a = set(cpu.a, 6);
    }
    
    fn set_7_b(cpu: &mut Cpu) {
        cpu.b = set(cpu.b, 7);
    }
    
    fn set_7_c(cpu: &mut Cpu) {
        cpu.c = set(cpu.c, 7);
    }
    
    fn set_7_d(cpu: &mut Cpu) {
        cpu.d = set(cpu.d, 7);
    }
    
    fn set_7_e(cpu: &mut Cpu) {
        cpu.e = set(cpu.e, 7);
    }
    
    fn set_7_h(cpu: &mut Cpu) {
        cpu.h = set(cpu.h, 7);
    }
    
    fn set_7_l(cpu: &mut Cpu) {
        cpu.l = set(cpu.l, 7);
    }
    
    fn set_7_mhl(cpu: &mut Cpu) {
        let hl = cpu.hl();
        let byte = cpu.mmu.read(hl);
        let value = set(byte, 7);
        cpu.mmu.write(hl, value);
    }
    
    fn set_7_a(cpu: &mut Cpu) {
        cpu.a = set(cpu.a, 7);
    }
    
    /// Helper function to set one bit in a u8.
    fn set(value: u8, bit: u8) -> u8 {
        value | (1u8 << (bit as usize))
    }
    
    
    /// Helper function to clear one bit in a u8.
    
    fn res(value: u8, bit: u8) -> u8 {
        value & !(1u8 << (bit as usize))
    }
    
    
    /// Helper function that rotates (shifts) left the given
    
    /// byte (probably from a register) and updates the
    /// proper flag registers.
    
    fn rl(cpu: &mut Cpu, value: u8) -> u8 {
    
        let carry = cpu.carry();
    
        cpu.set_carry((value & 0x80) == 0x80);
    
        let result = (value << 1) | carry as u8;
    
        cpu.set_sub(false);
        cpu.set_zero(result == 0);
        cpu.set_half_carry(false);
    
        result
    }
    
    
    fn rlc(cpu: &mut Cpu, value: u8) -> u8 {
    
        cpu.set_carry((value & 0x80) == 0x80);
    
    
        let result = (value << 1) | (value >> 7);
    
        cpu.set_sub(false);
        cpu.set_zero(result == 0);
        cpu.set_half_carry(false);
    
        result
    }
    
    
    /// Helper function that rotates (shifts) right the given
    /// byte (probably from a register) and updates the
    /// proper flag registers.
    fn rr(cpu: &mut Cpu, value: u8) -> u8 {
    
        let carry = cpu.carry();
    
        cpu.set_carry((value & 0x1) == 0x1);
    
    
        let result = (value >> 1) | ((carry as u8) << 7);
    
    
        cpu.set_sub(false);
        cpu.set_zero(result == 0);
        cpu.set_half_carry(false);
    
        result
    }
    
    
    fn rrc(cpu: &mut Cpu, value: u8) -> u8 {
    
        cpu.set_carry((value & 0x1) == 0x1);
    
    
        let result = (value >> 1) | (value << 7);
    
        cpu.set_sub(false);
        cpu.set_zero(result == 0);
        cpu.set_half_carry(false);
    
        result
    }
    
    
    /// Helper function to test one bit in a u8.
    /// Returns true if bit is 0.
    fn bit_zero(val: u8, bit: u8) -> bool {
        (val & (1u8 << (bit as usize))) == 0
    }
    
    
    fn bit_a(cpu: &mut Cpu, bit: u8) {
        cpu.set_sub(false);
        cpu.set_zero(bit_zero(cpu.a, bit));
        cpu.set_half_carry(true);
    }
    
    fn bit_b(cpu: &mut Cpu, bit: u8) {
        cpu.set_sub(false);
        cpu.set_zero(bit_zero(cpu.b, bit));
        cpu.set_half_carry(true);
    }
    
    fn bit_c(cpu: &mut Cpu, bit: u8) {
        cpu.set_sub(false);
        cpu.set_zero(bit_zero(cpu.c, bit));
        cpu.set_half_carry(true);
    }
    
    
    fn bit_d(cpu: &mut Cpu, bit: u8) {
        cpu.set_sub(false);
        cpu.set_zero(bit_zero(cpu.d, bit));
        cpu.set_half_carry(true);
    }
    
    
    fn bit_e(cpu: &mut Cpu, bit: u8) {
        cpu.set_sub(false);
        cpu.set_zero(bit_zero(cpu.e, bit));
        cpu.set_half_carry(true);
    }
    
    
    fn bit_h(cpu: &mut Cpu, bit: u8) {
        cpu.set_sub(false);
        cpu.set_zero(bit_zero(cpu.h, bit));
        cpu.set_half_carry(true);
    }
    
    
    fn bit_l(cpu: &mut Cpu, bit: u8) {
        cpu.set_sub(false);
        cpu.set_zero(bit_zero(cpu.l, bit));
        cpu.set_half_carry(true);
    }
    
    
    fn bit_mhl(cpu: &mut Cpu, bit: u8) {
    
        let byte = cpu.mmu.read(cpu.hl());
    
        cpu.set_sub(false);
    
        cpu.set_zero(bit_zero(byte, bit));
    
        cpu.set_half_carry(true);
    }
    
    
    fn add_set_flags(cpu: &mut Cpu, first: u8, second: u8) -> u8 {
        let first = first as u32;
        let second = second as u32;
    
    
        let result = first.wrapping_add(second);
        let result_b = result as u8;
    
    
        cpu.set_sub(false);
    
        cpu.set_zero(result_b == 0);
        cpu.set_half_carry((first ^ second ^ result) & 0x10 == 0x10);
    
        cpu.set_carry((result & 0x100) == 0x100);
    
        result_b
    
    fn add_carry_set_flags(cpu: &mut Cpu, first: u8, second: u8) -> u8 {
        let first = first as u32;
        let second = second as u32;
    
        let carry = cpu.carry() as u32;
    
    
        let result = first.wrapping_add(second).wrapping_add(carry);
        let result_b = result as u8;
    
        cpu.set_sub(false);
        cpu.set_zero(result_b == 0);
        cpu.set_half_carry((first ^ second ^ result) & 0x10 == 0x10);
    
        cpu.set_carry((result & 0x100) == 0x100);
    
    fn sub_set_flags(cpu: &mut Cpu, first: u8, second: u8) -> u8 {
        let first = first as u32;
        let second = second as u32;
    
    
        let result = first.wrapping_sub(second);
        let result_b = result as u8;
    
    
        cpu.set_sub(true);
    
        cpu.set_zero(result_b == 0);
        cpu.set_half_carry((first ^ second ^ result) & 0x10 == 0x10);
    
        cpu.set_carry((result & 0x100) == 0x100);
    
        result_b
    
    fn sub_carry_set_flags(cpu: &mut Cpu, first: u8, second: u8) -> u8 {
        let first = first as u32;
        let second = second as u32;
    
        let carry = cpu.carry() as u32;
    
    
        let result = first.wrapping_sub(second).wrapping_sub(carry);
        let result_b = result as u8;
    
        cpu.set_sub(true);
        cpu.set_zero(result_b == 0);
        cpu.set_half_carry((first ^ second ^ result) & 0x10 == 0x10);
    
        cpu.set_carry((result & 0x100) == 0x100);
    
    fn add_u16_u16(cpu: &mut Cpu, first: u16, second: u16) -> u16 {
        let first = first as u32;
        let second = second as u32;
    
        let result = first.wrapping_add(second);
    
    
        cpu.set_sub(false);
    
        cpu.set_half_carry((first ^ second ^ result) & 0x1000 == 0x1000);
    
        cpu.set_carry((result & 0x10000) == 0x10000);
    
        result as u16
    
    }
    
    fn swap(cpu: &mut Cpu, value: u8) -> u8 {
        cpu.set_sub(false);
        cpu.set_zero(value == 0);
        cpu.set_half_carry(false);
        cpu.set_carry(false);
    
        (value << 4) | (value >> 4)
    }
    
    
    /// Helper function to shift an `u8` to the left and update CPU
    /// flags.
    
    fn sla(cpu: &mut Cpu, value: u8) -> u8 {
    
        let result = value << 1;
    
        cpu.set_sub(false);
        cpu.set_zero(result == 0);
        cpu.set_half_carry(false);
    
        cpu.set_carry((value & 0x80) == 0x80);
    
    
        result
    }
    
    fn sra(cpu: &mut Cpu, value: u8) -> u8 {
        let result = (value >> 1) | (value & 0x80);
    
        cpu.set_sub(false);
        cpu.set_zero(result == 0);
        cpu.set_half_carry(false);
    
        cpu.set_carry((value & 0x1) == 0x1);
    
    fn srl(cpu: &mut Cpu, value: u8) -> u8 {
        let result = value >> 1;
    
        cpu.set_sub(false);
        cpu.set_zero(result == 0);
        cpu.set_half_carry(false);
    
        cpu.set_carry((value & 0x1) == 0x1);
    
    /// Helper function for RST instructions, pushes the
    /// current PC to the stack and jumps to the provided
    /// address.
    fn rst(cpu: &mut Cpu, addr: u16) {
        cpu.push_word(cpu.pc);
        cpu.pc = addr;
    }