Skip to content
Snippets Groups Projects
cpu.rs 2.39 KiB
Newer Older
  • Learn to ignore specific revisions
  • pub const RAM_SIZE: usize = 8192;
    
    pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 4] = [
        // 0x0 opcodes
        (nop, 4, "NOP"),
        (ld_bc_u16, 12, "LD BC, NN"),
        (ld_bc_a, 8, "LD BC, A"),
        // 0x2 opcodes
        (ld_sp_u16, 12, "LD SP, NN"),
    ];
    
    pub struct Cpu {
    
    João Magalhães's avatar
    João Magalhães committed
        pc: u16,
        sp: u16,
    
        reg_a: u8,
        reg_b: u8,
        reg_c: u8,
    
    João Magalhães's avatar
    João Magalhães committed
        reg_d: u8,
        reg_e: u8,
        reg_f: u8,
        reg_h: u8,
        reg_l: u8,
    
        ram: [u8; RAM_SIZE],
    
    João Magalhães's avatar
    João Magalhães committed
    }
    
    impl Cpu {
    
        pub fn new() -> Cpu {
            Cpu {
                pc: 0x0,
                sp: 0x0,
                reg_a: 0x0,
                reg_b: 0x0,
                reg_c: 0x0,
                reg_d: 0x0,
                reg_e: 0x0,
                reg_f: 0x0,
                reg_h: 0x0,
                reg_l: 0x0,
                ram: [0u8; RAM_SIZE],
            }
        }
    
        pub fn clock(&mut self) {
            // fetches the current instruction and increments
            // the PC (program counter) accordingly
            let instruction = self.ram[self.pc as usize];
            self.pc += 1;
        }
    
    
    João Magalhães's avatar
    João Magalhães committed
        #[inline(always)]
        fn reg_af(&self) -> u16 {
            (self.reg_a as u16) << 8 | self.reg_f as u16
        }
    
        #[inline(always)]
        fn reg_bc(&self) -> u16 {
            (self.reg_b as u16) << 8 | self.reg_c as u16
        }
    
        #[inline(always)]
        fn reg_de(&self) -> u16 {
            (self.reg_d as u16) << 8 | self.reg_e as u16
        }
    
        #[inline(always)]
        fn reg_hl(&self) -> u16 {
            (self.reg_h as u16) << 8 | self.reg_l as u16
        }
    
        #[inline(always)]
    
        fn read_u8(&mut self) -> u8 {
            let byte = self.ram[self.pc as usize];
            self.pc += 1;
            byte
        }
    
        #[inline(always)]
        fn read_u16(&mut self) -> u16 {
            let word = (self.ram[self.pc as usize] as u16) << 8 | self.ram[self.pc as usize + 1] as u16;
            self.pc += 2;
            word
        }
    
        #[inline(always)]
        fn get_zero(&self) -> bool {
    
    João Magalhães's avatar
    João Magalhães committed
            self.reg_f & 0x40 == 1
        }
    
        #[inline(always)]
    
        fn get_sub(&self) -> bool {
    
    João Magalhães's avatar
    João Magalhães committed
            self.reg_f & 0x20 == 1
        }
    
        #[inline(always)]
    
        fn get_half_carry(&self) -> bool {
    
    João Magalhães's avatar
    João Magalhães committed
            self.reg_f & 0x10 == 1
        }
    
        #[inline(always)]
    
        fn get_carry(&self) -> bool {
    
    João Magalhães's avatar
    João Magalhães committed
            self.reg_f & 0x08 == 1
        }
    
    
    fn nop(_cpu: &mut Cpu) {}
    
    fn ld_bc_u16(cpu: &mut Cpu) {
        cpu.reg_b = cpu.read_u8();
        cpu.reg_c = cpu.read_u8();
    }
    
    fn ld_bc_a(cpu: &mut Cpu) {
        cpu.ram[cpu.reg_bc() as usize] = cpu.reg_a;
    }
    
    fn ld_sp_u16(cpu: &mut Cpu) {
        cpu.sp = cpu.read_u16();
    }