Newer
Older
pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
(ld_mbc_a, 8, "LD [BC], A"),
(inc_bc, 8, "INC BC"),
(inc_b, 4, "INC B"),
(dec_b, 4, "DEC B"),
(rlca, 4, "RLCA"),
(ld_mu16_sp, 20, "LD [u16], SP"),
(add_hl_bc, 8, "ADD HL, BC"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(inc_de, 8, "INC DE"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(inc_hl, 8, "INC HL"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(ret_nz, 8, "RET NZ"),
(pop_bc, 12, "POP BC"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(ret, 16, "RET"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
pub const BITWISE: [(fn(&mut Cpu), u8, &'static str); 176] = [
// 0x0 opcodes
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
(nop, 4, "! UNIMP !"),
a: u8,
b: u8,
c: u8,
d: u8,
e: u8,
h: u8,
l: u8,
zero: bool,
sub: bool,
half_carry: bool,
carry: bool,
a: 0x0,
b: 0x0,
c: 0x0,
d: 0x0,
e: 0x0,
h: 0x0,
l: 0x0,
zero: false,
sub: false,
half_carry: false,
carry: false,
}
}
pub fn clock(&mut self) {
// fetches the current instruction and increments
// the PC (program counter) accordingly
let mut opcode = self.mmu.read(self.pc);
self.pc = self.pc.wrapping_add(1);
let instruction: &(fn(&mut Cpu), u8, &str);
opcode = self.mmu.read(self.pc);
self.pc = self.pc.wrapping_add(1);
instruction = &BITWISE[opcode as usize];
} else {
instruction = &INSTRUCTIONS[opcode as usize];
}
let (instruction_fn, instruction_time, instruction_str) = instruction;
println!(
"{}\t(0x{:02x})\t${:04x} {}",
instruction_str, opcode, pc, is_prefix
);
self.ticks = self.ticks.wrapping_add(*instruction_time as u32);
// calls the clock in the PPU to update its own
// execution lifecycle by one set of ticks
self.ppu().clock(*instruction_time);
#[inline(always)]
pub fn mmu(&mut self) -> &mut Mmu {
&mut self.mmu
}
#[inline(always)]
pub fn ppu(&mut self) -> &mut Ppu {
self.mmu().ppu()
}
#[inline(always)]
pub fn ticks(&self) -> u32 {
self.ticks
}
#[inline(always)]
pub fn pc(&self) -> u16 {
self.pc
}
#[inline(always)]
pub fn sp(&self) -> u16 {
self.sp
}
fn af(&self) -> u16 {
(self.a as u16) << 8 | self.f() as u16
fn bc(&self) -> u16 {
(self.b as u16) << 8 | self.c as u16
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
fn f(&self) -> u8 {
let mut f = 0x0u8;
if self.zero {
f |= 0x80;
}
if self.sub {
f |= 0x40;
}
if self.half_carry {
f |= 0x20;
}
if self.carry {
f |= 0x10;
}
f
}
#[inline(always)]
fn set_bc(&mut self, value: u16) {
self.b = (value >> 8) as u8;
self.c = value as u8;
}
#[inline(always)]
fn de(&self) -> u16 {
(self.d as u16) << 8 | self.e as u16
}
#[inline(always)]
fn set_de(&mut self, value: u16) {
self.d = (value >> 8) as u8;
self.e = value as u8;
fn hl(&self) -> u16 {
(self.h as u16) << 8 | self.l as u16
}
#[inline(always)]
fn set_hl(&mut self, value: u16) {
self.h = (value >> 8) as u8;
self.l = value as u8;
byte
}
#[inline(always)]
fn read_u16(&mut self) -> u16 {
let byte1 = self.read_u8();
let byte2 = self.read_u8();
let word = byte1 as u16 | ((byte2 as u16) << 8);
self.mmu.write(self.sp, byte);
}
#[inline(always)]
fn push_word(&mut self, word: u16) {
self.push_byte((word >> 8) as u8);
self.push_byte(word as u8);
}
#[inline(always)]
fn pop_byte(&mut self) -> u8 {
let byte = self.mmu.read(self.sp);
byte
}
#[inline(always)]
fn pop_word(&mut self) -> u16 {
let word = self.pop_byte() as u16 | ((self.pop_byte() as u16) << 8);
word
}
#[inline(always)]
fn get_zero(&self) -> bool {
self.zero
}
#[inline(always)]
fn set_zero(&mut self, value: bool) {
self.zero = value
self.sub
}
#[inline(always)]
fn set_sub(&mut self, value: bool) {
self.sub = value;
self.half_carry
}
#[inline(always)]
fn set_half_carry(&mut self, value: bool) {
self.half_carry = value
self.carry
}
#[inline(always)]
fn set_carry(&mut self, value: bool) {
self.carry = value;
fn nop(_cpu: &mut Cpu) {}
fn ld_bc_u16(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.set_bc(word);
}
fn ld_mbc_a(cpu: &mut Cpu) {
}
fn inc_bc(cpu: &mut Cpu) {
cpu.set_bc(cpu.bc().wrapping_add(1));
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
fn inc_b(cpu: &mut Cpu) {
let value = cpu.b.wrapping_add(1);
cpu.set_sub(false);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.b = value;
}
fn dec_b(cpu: &mut Cpu) {
let value = cpu.b.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.b = value;
}
fn ld_b_u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.b = byte;
}
fn rlca(cpu: &mut Cpu) {
let carry = cpu.a >> 7;
cpu.a = cpu.a << 1 | carry;
cpu.set_sub(false);
cpu.set_zero(false);
cpu.set_half_carry(false);
cpu.set_carry(carry == 1);
}
fn ld_mu16_sp(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.mmu.write(word, cpu.sp as u8);
cpu.mmu.write(word + 1, (cpu.sp >> 8) as u8);
let value = add_u16_u16(cpu, cpu.hl(), cpu.bc());
cpu.set_hl(value);
fn inc_c(cpu: &mut Cpu) {
let value = cpu.c.wrapping_add(1);
cpu.set_sub(false);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.c = value;
}
fn dec_c(cpu: &mut Cpu) {
let value = cpu.c.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.c = value;
}
fn ld_c_u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.c = byte;
}
fn ld_de_u16(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.set_de(word);
}
fn inc_de(cpu: &mut Cpu) {
cpu.set_de(cpu.de().wrapping_add(1));
}
fn rla(cpu: &mut Cpu) {
let carry = cpu.get_carry();
cpu.set_carry(cpu.a & 0x80 == 0x80);
cpu.a = cpu.a << 1 | carry as u8;
cpu.set_sub(false);
cpu.set_zero(false);
cpu.set_half_carry(false);
}
fn jr_i8(cpu: &mut Cpu) {
let byte = cpu.read_u8() as i8;
cpu.pc = (cpu.pc as i16).wrapping_add(byte as i16) as u16;
}
fn ld_a_mde(cpu: &mut Cpu) {
let byte = cpu.mmu.read(cpu.de());
cpu.a = byte;
}
fn ld_e_u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.e = byte;
}
fn jr_nz_i8(cpu: &mut Cpu) {
let byte = cpu.read_u8() as i8;
if cpu.get_zero() {
return;
}
cpu.pc = (cpu.pc as i16).wrapping_add(byte as i16) as u16;
cpu.ticks = cpu.ticks.wrapping_add(4);
fn ld_hl_u16(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.set_hl(word);
}
fn ld_mhli_a(cpu: &mut Cpu) {
cpu.mmu.write(cpu.hl(), cpu.a);
cpu.set_hl(cpu.hl().wrapping_add(1));
}
fn inc_hl(cpu: &mut Cpu) {
cpu.set_hl(cpu.hl().wrapping_add(1));
}
fn jr_z_i8(cpu: &mut Cpu) {
let byte = cpu.read_u8() as i8;
if !cpu.get_zero() {
return;
}
cpu.pc = (cpu.pc as i16).wrapping_add(byte as i16) as u16;
cpu.ticks = cpu.ticks.wrapping_add(4);
}
fn ld_l_u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.l = byte;
}
fn ld_sp_u16(cpu: &mut Cpu) {
cpu.sp = cpu.read_u16();
}
fn ld_mhld_a(cpu: &mut Cpu) {
cpu.mmu.write(cpu.hl(), cpu.a);
cpu.set_hl(cpu.hl().wrapping_sub(1));
}
fn dec_a(cpu: &mut Cpu) {
let value = cpu.a.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.a = value;
}
fn ld_a_u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.a = byte;
}
fn ld_b_h(cpu: &mut Cpu) {
cpu.b = cpu.h;
}
fn ld_c_a(cpu: &mut Cpu) {
cpu.c = cpu.a;
}
fn ld_d_a(cpu: &mut Cpu) {
cpu.d = cpu.a;
}
fn ld_h_a(cpu: &mut Cpu) {
cpu.h = cpu.a;
}
fn ld_mhl_a(cpu: &mut Cpu) {
cpu.mmu.write(cpu.hl(), cpu.a);
}
fn ld_a_e(cpu: &mut Cpu) {
cpu.a = cpu.e;
}
cpu.a ^= cpu.a;
cpu.set_sub(false);
cpu.set_zero(cpu.a == 0);
cpu.set_half_carry(false);
cpu.set_carry(false);
fn ret_nz(cpu: &mut Cpu) {
if cpu.get_zero() {
return;
}
cpu.pc = cpu.pop_word();
cpu.ticks = cpu.ticks.wrapping_add(12);
}
fn pop_bc(cpu: &mut Cpu) {
let word = cpu.pop_word();
cpu.set_bc(word);
}
fn push_bc(cpu: &mut Cpu) {
cpu.push_word(cpu.bc());
}
fn ret(cpu: &mut Cpu) {
cpu.pc = cpu.pop_word();
}
let word = cpu.read_u16();
cpu.push_word(cpu.pc);
cpu.pc = word;
fn ld_mff00u8_a(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.mmu.write(0xff00 + byte as u16, cpu.a);
cpu.mmu.write(0xff00 + cpu.c as u16, cpu.a);
fn ld_mu16_a(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.mmu.write(word, cpu.a);
}
fn ld_a_mff00u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.a = cpu.mmu.read(0xff00 + byte as u16);
}
fn cp_a_u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
sub_set_flags(cpu, cpu.a, byte);
}
fn rl_c(cpu: &mut Cpu) {
cpu.c = rl(cpu, cpu.c);
}
fn bit_7_h(cpu: &mut Cpu) {
bit_h(cpu, 7);
}
/// Helper function that rotates (shifts) the given
/// byte (probably from a register) and updates the
/// proper flag registers.
fn rl(cpu: &mut Cpu, byte: u8) -> u8 {
let carry = cpu.get_carry();
cpu.set_carry(byte & 0x80 == 0x80);
let result = (byte << 1) | carry as u8;
cpu.set_sub(false);
cpu.set_zero(result == 0);
cpu.set_half_carry(false);
result