diff --git a/src/cpu.rs b/src/cpu.rs index 337e9eb..b915437 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -1,107 +1,110 @@ +use crate::mmu::MMU; use crate::mode::GBMode; use crate::registers::{Registers, Flags}; pub struct CPU { - reg: Registers + reg: Registers, + mem: MMU } impl CPU { pub fn new(mode: GBMode) -> CPU { CPU { - reg: Registers::new(mode) + reg: Registers::new(mode), + mem: MMU::new() } } pub fn call(&mut self, opcode: u8) -> u32 { match opcode { - 0x40 => { self.reg.b = self.reg.b; 1 }, - 0x41 => { self.reg.b = self.reg.c; 1 }, - 0x42 => { self.reg.b = self.reg.d; 1 }, - 0x43 => { self.reg.b = self.reg.e; 1 }, - 0x44 => { self.reg.b = self.reg.h; 1 }, - 0x45 => { self.reg.b = self.reg.l; 1 }, - 0x46 => { 2 }, // LD B, HL - 0x47 => { self.reg.b = self.reg.a; 1 }, - 0x48 => { self.reg.c = self.reg.b; 1 }, - 0x49 => { self.reg.c = self.reg.c; 1 }, - 0x4A => { self.reg.c = self.reg.d; 1 }, - 0x4B => { self.reg.c = self.reg.e; 1 }, - 0x4C => { self.reg.c = self.reg.h; 1 }, - 0x4D => { self.reg.c = self.reg.l; 1 }, - 0x4E => { 2 }, // LD C, HL - 0x4F => { self.reg.c = self.reg.a; 1 }, - 0x50 => { self.reg.d = self.reg.b; 1 }, - 0x51 => { self.reg.d = self.reg.c; 1 }, - 0x52 => { self.reg.d = self.reg.d; 1 }, - 0x53 => { self.reg.d = self.reg.e; 1 }, - 0x54 => { self.reg.d = self.reg.l; 1 }, - 0x56 => { 2 }, // LD D, HL - 0x57 => { self.reg.d = self.reg.a; 1 }, - 0x58 => { self.reg.e = self.reg.b; 1 }, - 0x59 => { self.reg.e = self.reg.c; 1 }, - 0x5A => { self.reg.e = self.reg.d; 1 }, - 0x5B => { self.reg.e = self.reg.e; 1 }, - 0x5C => { self.reg.e = self.reg.h; 1 }, - 0x5D => { self.reg.e = self.reg.l; 1 }, - 0x5E => { 2 }, // LD E, HL - 0x5F => { self.reg.e = self.reg.a; 1 }, - 0x60 => { self.reg.h = self.reg.b; 1 }, - 0x61 => { self.reg.h = self.reg.c; 1 }, - 0x62 => { self.reg.h = self.reg.d; 1 }, - 0x63 => { self.reg.h = self.reg.e; 1 }, - 0x64 => { self.reg.h = self.reg.h; 1 }, - 0x65 => { self.reg.h = self.reg.l; 1 }, - 0x66 => { 2 }, // LD H, HL - 0x67 => { self.reg.h = self.reg.a; 1 }, - 0x68 => { self.reg.l = self.reg.b; 1 }, - 0x69 => { self.reg.l = self.reg.c; 1 }, - 0x6A => { self.reg.l = self.reg.d; 1 }, - 0x6B => { self.reg.l = self.reg.e; 1 }, - 0x6C => { self.reg.l = self.reg.h; 1 }, - 0x6D => { self.reg.l = self.reg.l; 1 }, - 0x6E => { 2 }, // LD L, HL, - 0x6F => { self.reg.l = self.reg.a; 1 }, - 0x78 => { self.reg.a = self.reg.b; 1 }, - 0x79 => { self.reg.a = self.reg.c; 1 }, - 0x7A => { self.reg.a = self.reg.d; 1 }, - 0x7B => { self.reg.a = self.reg.e; 1 }, - 0x7C => { self.reg.a = self.reg.h; 1 }, - 0x7D => { self.reg.a = self.reg.l; 1 }, - 0x7E => { 2 }, // LD A, HL - 0x7F => { self.reg.a = self.reg.a; 1 }, - 0x80 => { self.alu_add(self.reg.b); 1 }, - 0x81 => { self.alu_add(self.reg.c); 1 }, - 0x82 => { self.alu_add(self.reg.d); 1 }, - 0x83 => { self.alu_add(self.reg.e); 1 }, - 0x84 => { self.alu_add(self.reg.h); 1 }, - 0x85 => { self.alu_add(self.reg.l); 1 }, - 0x86 => { 2 }, // ADD A, HL - 0x87 => { self.alu_add(self.reg.a); 1 }, - 0x88 => { self.alu_adc(self.reg.b); 1 }, - 0x89 => { self.alu_adc(self.reg.c); 1 }, - 0x8A => { self.alu_adc(self.reg.d); 1 }, - 0x8B => { self.alu_adc(self.reg.e); 1 }, - 0x8C => { self.alu_adc(self.reg.h); 1 }, - 0x8D => { self.alu_adc(self.reg.l); 1 }, - 0x8E => { 2 }, // ADC A, HL - 0x8F => { self.alu_adc(self.reg.a); 1 }, - 0x90 => { self.alu_sub(self.reg.b); 1 }, - 0x91 => { self.alu_sub(self.reg.c); 1 }, - 0x92 => { self.alu_sub(self.reg.d); 1 }, - 0x93 => { self.alu_sub(self.reg.e); 1 }, - 0x94 => { self.alu_sub(self.reg.h); 1 }, - 0x95 => { self.alu_sub(self.reg.l); 1 }, - 0x96 => { 2 }, // SUB A, HL - 0x97 => { self.alu_sub(self.reg.a); 1 }, - 0x98 => { self.alu_sbc(self.reg.b); 1 }, - 0x99 => { self.alu_sbc(self.reg.c); 1 }, - 0x9A => { self.alu_sbc(self.reg.d); 1 }, - 0x9B => { self.alu_sbc(self.reg.e); 1 }, - 0x9C => { self.alu_sbc(self.reg.h); 1 }, - 0x9D => { self.alu_sbc(self.reg.l); 1 }, - 0x9E => { 2 }, // SBC A, HL - 0x9F => { self.alu_sbc(self.reg.a); 1 }, - 0xCB => { 0 }, // CB OPs + 0x40 => { self.reg.b = self.reg.b; 1 }, + 0x41 => { self.reg.b = self.reg.c; 1 }, + 0x42 => { self.reg.b = self.reg.d; 1 }, + 0x43 => { self.reg.b = self.reg.e; 1 }, + 0x44 => { self.reg.b = self.reg.h; 1 }, + 0x45 => { self.reg.b = self.reg.l; 1 }, + 0x46 => { self.reg.b = self.mem.read(self.reg.get_hl()); 2 }, + 0x47 => { self.reg.b = self.reg.a; 1 }, + 0x48 => { self.reg.c = self.reg.b; 1 }, + 0x49 => { self.reg.c = self.reg.c; 1 }, + 0x4A => { self.reg.c = self.reg.d; 1 }, + 0x4B => { self.reg.c = self.reg.e; 1 }, + 0x4C => { self.reg.c = self.reg.h; 1 }, + 0x4D => { self.reg.c = self.reg.l; 1 }, + 0x4E => { self.reg.c = self.mem.read(self.reg.get_hl()); 2 }, + 0x4F => { self.reg.c = self.reg.a; 1 }, + 0x50 => { self.reg.d = self.reg.b; 1 }, + 0x51 => { self.reg.d = self.reg.c; 1 }, + 0x52 => { self.reg.d = self.reg.d; 1 }, + 0x53 => { self.reg.d = self.reg.e; 1 }, + 0x54 => { self.reg.d = self.reg.l; 1 }, + 0x56 => { self.reg.d = self.mem.read(self.reg.get_hl()); 2 }, + 0x57 => { self.reg.d = self.reg.a; 1 }, + 0x58 => { self.reg.e = self.reg.b; 1 }, + 0x59 => { self.reg.e = self.reg.c; 1 }, + 0x5A => { self.reg.e = self.reg.d; 1 }, + 0x5B => { self.reg.e = self.reg.e; 1 }, + 0x5C => { self.reg.e = self.reg.h; 1 }, + 0x5D => { self.reg.e = self.reg.l; 1 }, + 0x5E => { self.reg.e = self.mem.read(self.reg.get_hl()); 2 }, + 0x5F => { self.reg.e = self.reg.a; 1 }, + 0x60 => { self.reg.h = self.reg.b; 1 }, + 0x61 => { self.reg.h = self.reg.c; 1 }, + 0x62 => { self.reg.h = self.reg.d; 1 }, + 0x63 => { self.reg.h = self.reg.e; 1 }, + 0x64 => { self.reg.h = self.reg.h; 1 }, + 0x65 => { self.reg.h = self.reg.l; 1 }, + 0x66 => { self.reg.h = self.mem.read(self.reg.get_hl()); 2 }, + 0x67 => { self.reg.h = self.reg.a; 1 }, + 0x68 => { self.reg.l = self.reg.b; 1 }, + 0x69 => { self.reg.l = self.reg.c; 1 }, + 0x6A => { self.reg.l = self.reg.d; 1 }, + 0x6B => { self.reg.l = self.reg.e; 1 }, + 0x6C => { self.reg.l = self.reg.h; 1 }, + 0x6D => { self.reg.l = self.reg.l; 1 }, + 0x6E => { self.reg.l = self.mem.read(self.reg.get_hl()); 2 }, + 0x6F => { self.reg.l = self.reg.a; 1 }, + 0x78 => { self.reg.a = self.reg.b; 1 }, + 0x79 => { self.reg.a = self.reg.c; 1 }, + 0x7A => { self.reg.a = self.reg.d; 1 }, + 0x7B => { self.reg.a = self.reg.e; 1 }, + 0x7C => { self.reg.a = self.reg.h; 1 }, + 0x7D => { self.reg.a = self.reg.l; 1 }, + 0x7E => { self.reg.a = self.mem.read(self.reg.get_hl()); 2 }, + 0x7F => { self.reg.a = self.reg.a; 1 }, + 0x80 => { self.alu_add(self.reg.b); 1 }, + 0x81 => { self.alu_add(self.reg.c); 1 }, + 0x82 => { self.alu_add(self.reg.d); 1 }, + 0x83 => { self.alu_add(self.reg.e); 1 }, + 0x84 => { self.alu_add(self.reg.h); 1 }, + 0x85 => { self.alu_add(self.reg.l); 1 }, + 0x86 => { self.alu_add(self.mem.read(self.reg.get_hl())); 2 }, + 0x87 => { self.alu_add(self.reg.a); 1 }, + 0x88 => { self.alu_adc(self.reg.b); 1 }, + 0x89 => { self.alu_adc(self.reg.c); 1 }, + 0x8A => { self.alu_adc(self.reg.d); 1 }, + 0x8B => { self.alu_adc(self.reg.e); 1 }, + 0x8C => { self.alu_adc(self.reg.h); 1 }, + 0x8D => { self.alu_adc(self.reg.l); 1 }, + 0x8E => { self.alu_adc(self.mem.read(self.reg.get_hl())); 2 }, + 0x8F => { self.alu_adc(self.reg.a); 1 }, + 0x90 => { self.alu_sub(self.reg.b); 1 }, + 0x91 => { self.alu_sub(self.reg.c); 1 }, + 0x92 => { self.alu_sub(self.reg.d); 1 }, + 0x93 => { self.alu_sub(self.reg.e); 1 }, + 0x94 => { self.alu_sub(self.reg.h); 1 }, + 0x95 => { self.alu_sub(self.reg.l); 1 }, + 0x96 => { self.alu_sub(self.mem.read(self.reg.get_hl())); 2 }, + 0x97 => { self.alu_sub(self.reg.a); 1 }, + 0x98 => { self.alu_sbc(self.reg.b); 1 }, + 0x99 => { self.alu_sbc(self.reg.c); 1 }, + 0x9A => { self.alu_sbc(self.reg.d); 1 }, + 0x9B => { self.alu_sbc(self.reg.e); 1 }, + 0x9C => { self.alu_sbc(self.reg.h); 1 }, + 0x9D => { self.alu_sbc(self.reg.l); 1 }, + 0x9E => { self.alu_sbc(self.mem.read(self.reg.get_hl())); 2 }, + 0x9F => { self.alu_sbc(self.reg.a); 1 }, + 0xCB => { 0 }, // CB OPs code => panic!("Instruction {:2X} is unknown!", code), } } diff --git a/src/mmu.rs b/src/mmu.rs index 10d302e..dcae114 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -5,6 +5,14 @@ pub struct MMU { } impl MMU { + pub fn new() -> MMU { + MMU { + wram: [0; 0x8000], + hram: [0; 0x7f], + interrupt: 0, + } + } + pub fn read(&self, a: u16) -> u8 { match a { 0xC000..=0xCFFF => self.wram[a as usize - 0xC000],