Skip to content
Snippets Groups Projects
Verified Commit 96c51b90 authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

refactor: moved instructions to another file

parent 19babd32
No related branches found
No related tags found
No related merge requests found
use crate::{mmu::Mmu, ppu::Ppu};
use crate::{
inst::{BITWISE, INSTRUCTIONS},
mmu::Mmu,
ppu::Ppu,
};
pub const PREFIX: u8 = 0xcb;
pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
// 0x0 opcodes
(nop, 4, "NOP"),
(ld_bc_u16, 12, "LD BC, u16"),
(ld_mbc_a, 8, "LD [BC], A"),
(inc_bc, 8, "INC BC"),
(inc_b, 4, "INC B"),
(dec_b, 4, "DEC B"),
(ld_b_u8, 8, "LD B, u8"),
(rlca, 4, "RLCA"),
(ld_mu16_sp, 20, "LD [u16], SP"),
(add_hl_bc, 8, "ADD HL, BC"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(inc_c, 4, "INC C"),
(dec_c, 4, "DEC C"),
(ld_c_u8, 8, "LD C, u8"),
(noimpl, 4, "! UNIMP !"),
// 0x1 opcodes
(noimpl, 4, "! UNIMP !"),
(ld_de_u16, 12, "LD DE, u16"),
(noimpl, 4, "! UNIMP !"),
(inc_de, 8, "INC DE"),
(noimpl, 4, "! UNIMP !"),
(dec_d, 4, "DEC D"),
(noimpl, 4, "! UNIMP !"),
(rla, 4, "RLA"),
(jr_i8, 12, "JR i8"),
(noimpl, 4, "! UNIMP !"),
(ld_a_mde, 8, "LD A, [DE]"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(dec_e, 4, "DEC E"),
(ld_e_u8, 8, "LD E, u8"),
(noimpl, 4, "! UNIMP !"),
// 0x2 opcodes
(jr_nz_i8, 8, "JR NZ, i8"),
(ld_hl_u16, 12, "LD HL, u16"),
(ld_mhli_a, 8, "LD [HL+], A"),
(inc_hl, 8, "INC HL"),
(inc_h, 4, "INC H"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(jr_z_i8, 8, "JR Z, i8"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ld_l_u8, 8, "LD L, u8"),
(noimpl, 4, "! UNIMP !"),
// 0x3 opcodes
(noimpl, 4, "! UNIMP !"),
(ld_sp_u16, 12, "LD SP, u16"),
(ld_mhld_a, 8, "LD [HL-], A"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(dec_a, 4, "DEC A"),
(ld_a_u8, 8, "LD A, u8"),
(noimpl, 4, "! UNIMP !"),
// 0x4 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ld_b_h, 4, "LD B, H"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ld_c_a, 4, "LD C, A"),
// 0x5 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ld_d_a, 4, "LD D, A"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x6 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ld_h_a, 4, "LD H, A"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x7 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ld_mhl_a, 8, "LD [HL], A"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ld_a_e, 4, "LD A, E"),
(ld_a_h, 4, "LD A, H"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x8 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x9 opcodes
(sub_a_b, 4, "SUB A, B"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0xa opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(xor_a_a, 4, "XOR A, A"),
// 0xb opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0xc opcodes
(ret_nz, 8, "RET NZ"),
(pop_bc, 12, "POP BC"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(push_bc, 16, "PUSH BC"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ret, 16, "RET"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(call_u16, 24, "CALL u16"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0xd opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0xe opcodes
(ld_mff00u8_a, 12, "LD [FF00+u8], A"),
(noimpl, 4, "! UNIMP !"),
(ld_mff00c_a, 8, "LD [FF00+C], A"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(ld_mu16_a, 16, "LD [u16], A"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0xf opcodes
(ld_a_mff00u8, 12, "LD A, [FF00+u8]"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(cp_a_u8, 8, "CP A, u8"),
(noimpl, 4, "! UNIMP !"),
];
pub const BITWISE: [(fn(&mut Cpu), u8, &'static str); 176] = [
// 0x0 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x1 opcodes
(noimpl, 4, "! UNIMP !"),
(rl_c, 8, "RL C"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x2 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x3 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x4 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x5 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x6 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x7 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(bit_7_h, 8, "BIT 7, H"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x8 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0x9 opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
// 0xa opcodes
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
(noimpl, 4, "! UNIMP !"),
];
pub struct Cpu {
pc: u16,
sp: u16,
a: u8,
b: u8,
c: u8,
d: u8,
e: u8,
h: u8,
l: u8,
pub pc: u16,
pub sp: u16,
pub a: u8,
pub b: u8,
pub c: u8,
pub d: u8,
pub e: u8,
pub h: u8,
pub l: u8,
zero: bool,
sub: bool,
half_carry: bool,
carry: bool,
mmu: Mmu,
ticks: u32,
pub mmu: Mmu,
pub ticks: u32,
}
impl Cpu {
......@@ -538,7 +77,7 @@ impl Cpu {
println!("GOING TO PLAY BOOT SOUND");
}
if pc == 0x008f {
if pc == 0x00e0 {
println!("GOING TO PLAY BOOT 0x00e0");
}
......@@ -579,17 +118,17 @@ impl Cpu {
}
#[inline(always)]
fn af(&self) -> u16 {
pub fn af(&self) -> u16 {
(self.a as u16) << 8 | self.f() as u16
}
#[inline(always)]
fn bc(&self) -> u16 {
pub fn bc(&self) -> u16 {
(self.b as u16) << 8 | self.c as u16
}
#[inline(always)]
fn f(&self) -> u8 {
pub fn f(&self) -> u8 {
let mut f = 0x0u8;
if self.zero {
f |= 0x80;
......@@ -607,42 +146,42 @@ impl Cpu {
}
#[inline(always)]
fn set_bc(&mut self, value: u16) {
pub fn set_bc(&mut self, value: u16) {
self.b = (value >> 8) as u8;
self.c = value as u8;
}
#[inline(always)]
fn de(&self) -> u16 {
pub fn de(&self) -> u16 {
(self.d as u16) << 8 | self.e as u16
}
#[inline(always)]
fn set_de(&mut self, value: u16) {
pub fn set_de(&mut self, value: u16) {
self.d = (value >> 8) as u8;
self.e = value as u8;
}
#[inline(always)]
fn hl(&self) -> u16 {
pub fn hl(&self) -> u16 {
(self.h as u16) << 8 | self.l as u16
}
#[inline(always)]
fn set_hl(&mut self, value: u16) {
pub fn set_hl(&mut self, value: u16) {
self.h = (value >> 8) as u8;
self.l = value as u8;
}
#[inline(always)]
fn read_u8(&mut self) -> u8 {
pub fn read_u8(&mut self) -> u8 {
let byte = self.mmu.read(self.pc);
self.pc = self.pc.wrapping_add(1);
byte
}
#[inline(always)]
fn read_u16(&mut self) -> u16 {
pub 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);
......@@ -650,452 +189,67 @@ impl Cpu {
}
#[inline(always)]
fn push_byte(&mut self, byte: u8) {
pub fn push_byte(&mut self, byte: u8) {
self.sp = self.sp.wrapping_sub(1);
self.mmu.write(self.sp, byte);
}
#[inline(always)]
fn push_word(&mut self, word: u16) {
pub 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 {
pub fn pop_byte(&mut self) -> u8 {
let byte = self.mmu.read(self.sp);
self.sp = self.sp.wrapping_add(1);
byte
}
#[inline(always)]
fn pop_word(&mut self) -> u16 {
pub 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 {
pub fn get_zero(&self) -> bool {
self.zero
}
#[inline(always)]
fn set_zero(&mut self, value: bool) {
pub fn set_zero(&mut self, value: bool) {
self.zero = value
}
#[inline(always)]
fn get_sub(&self) -> bool {
pub fn get_sub(&self) -> bool {
self.sub
}
#[inline(always)]
fn set_sub(&mut self, value: bool) {
pub fn set_sub(&mut self, value: bool) {
self.sub = value;
}
#[inline(always)]
fn get_half_carry(&self) -> bool {
pub fn get_half_carry(&self) -> bool {
self.half_carry
}
#[inline(always)]
fn set_half_carry(&mut self, value: bool) {
pub fn set_half_carry(&mut self, value: bool) {
self.half_carry = value
}
#[inline(always)]
fn get_carry(&self) -> bool {
pub fn get_carry(&self) -> bool {
self.carry
}
#[inline(always)]
fn set_carry(&mut self, value: bool) {
pub fn set_carry(&mut self, value: bool) {
self.carry = value;
}
}
fn nop(_cpu: &mut Cpu) {}
fn noimpl(_cpu: &mut Cpu) {
todo!("Instruction not implemented");
}
fn ld_bc_u16(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.set_bc(word);
}
fn ld_mbc_a(cpu: &mut Cpu) {
cpu.mmu.write(cpu.bc(), cpu.a);
}
fn inc_bc(cpu: &mut Cpu) {
cpu.set_bc(cpu.bc().wrapping_add(1));
}
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 b = cpu.b;
let value = b.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((b & 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);
}
fn add_hl_bc(cpu: &mut Cpu) {
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 c = cpu.c;
let value = c.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((c & 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 dec_d(cpu: &mut Cpu) {
let d = cpu.d;
let value = d.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((d & 0xf) == 0xf);
cpu.d = value;
}
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 dec_e(cpu: &mut Cpu) {
let e = cpu.e;
let value = e.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((e & 0xf) == 0xf);
cpu.e = value;
}
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 inc_h(cpu: &mut Cpu) {
let value = cpu.h.wrapping_add(1);
cpu.set_sub(false);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.h = value;
}
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 a = cpu.a;
let value = a.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((a & 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;
}
fn ld_a_h(cpu: &mut Cpu) {
cpu.a = cpu.h;
}
fn sub_a_b(cpu: &mut Cpu) {
cpu.a = sub_set_flags(cpu, cpu.a, cpu.b);
}
fn xor_a_a(cpu: &mut Cpu) {
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();
}
fn call_u16(cpu: &mut Cpu) {
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);
}
fn ld_mff00c_a(cpu: &mut Cpu) {
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
}
/// 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_h(cpu: &mut Cpu, bit: u8) {
cpu.set_sub(false);
cpu.set_zero(bit_zero(cpu.h, bit));
cpu.set_half_carry(true);
}
fn sub_set_flags(cpu: &mut Cpu, x: u8, y: u8) -> u8 {
// checks for borrow using 32bit arithmetics
let x = x as u32;
let y = y as u32;
let value = x.wrapping_sub(y);
let value_b = value as u8;
cpu.set_sub(true);
cpu.set_carry(value & 0x100 == 0x100);
cpu.set_zero(value_b == 0);
cpu.set_half_carry((x ^ y ^ value) & 0x10 == 0x10);
value_b
}
fn add_u16_u16(cpu: &mut Cpu, first: u16, second: u16) -> u16 {
let first = first as u32;
let second = second as u32;
let value = first.wrapping_add(second);
cpu.set_sub(false);
cpu.set_carry(value & 0x10000 == 0x10000);
cpu.set_half_carry((first ^ second ^ value) & 0x1000 == 0x1000);
value as u16
}
This diff is collapsed.
pub mod cpu;
pub mod gb;
pub mod inst;
pub mod mmu;
pub mod ppu;
pub mod util;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment