diff --git a/src/bus.rs b/src/bus.rs index 38608ef..2f9f7c3 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -1,4 +1,5 @@ use super::cartridge::Cartridge; +use super::high_ram::HighRAM; use super::interrupt::Interrupt; use super::ppu::PPU; use super::sound::Sound; @@ -15,6 +16,7 @@ pub struct Bus { timer: Timer, interrupt: Interrupt, sound: Sound, + hram: HighRAM, } impl Default for Bus { @@ -28,6 +30,7 @@ impl Default for Bus { timer: Default::default(), interrupt: Default::default(), sound: Default::default(), + hram: Default::default(), } } } @@ -111,7 +114,7 @@ impl Bus { } 0xFF80..=0xFFFE => { // High RAM - unimplemented!("Unable to read {:#06X} in High RAM", addr); + self.hram.read_byte((addr - 0xFF80) as usize) } 0xFFFF => { // Interupts Enable Register @@ -175,7 +178,7 @@ impl Bus { } 0xFF80..=0xFFFE => { // High RAM - unimplemented!("Unable to write to {:#06X} in High RAM", addr); + self.hram.write_byte((addr - 0xFF80) as usize, byte); } 0xFFFF => { // Interupts Enable Register diff --git a/src/cpu.rs b/src/cpu.rs index 150f482..2dca39c 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -1,5 +1,6 @@ use super::bus::Bus; use super::instruction::Instruction; +use std::fmt::{Display, Formatter, Result as FmtResult}; #[derive(Debug, Clone, Default)] pub struct Cpu { @@ -60,7 +61,28 @@ impl Cpu { } pub fn decode(&mut self, opcode: u8) -> Instruction { - Instruction::from_byte(self, opcode) + let tmp = Instruction::from_byte(self, opcode); + + let a = self.register(Register::A); + let flag: Flags = self.register(Register::Flag).into(); + let bc = self.register_pair(RegisterPair::BC); + let de = self.register_pair(RegisterPair::DE); + let hl = self.register_pair(RegisterPair::HL); + let sp = self.register_pair(RegisterPair::SP); + + println!( + "A: {:#04X} | BC: {:#06X} | DE: {:#06X} | HL: {:#06X} | SP: {:#06X} | {}", + a, bc, de, hl, sp, flag + ); + + // Get info from serial port + // if self.bus.read_byte(0xFF02) == 0x81 { + // let c = self.bus.read_byte(0xFF01) as char; + // self.bus.write_byte(0xFF02, 0x00); + // print!("TEST RESULT!: {}", c); + // } + + tmp } pub fn execute(&mut self, instruction: Instruction) { @@ -68,6 +90,24 @@ impl Cpu { } } +impl Cpu { + pub fn dbg_read_byte(&self, addr: u16) -> u8 { + self.bus.read_byte(addr) + } + + pub fn dbg_write_byte(&mut self, addr: u16, byte: u8) { + self.bus.write_byte(addr, byte); + } + + pub fn dbg_read_word(&self, addr: u16) -> u16 { + self.bus.read_word(addr) + } + + pub fn dbg_write_word(&mut self, addr: u16, word: u16) { + self.bus.write_word(addr, word) + } +} + impl Cpu { pub fn read_byte(&mut self, addr: u16) -> u8 { let byte = self.bus.read_byte(addr); @@ -223,6 +263,34 @@ impl Flags { } } +impl Display for Flags { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + if self.z { + f.write_str("Z")?; + } else { + f.write_str("_")?; + } + + if self.n { + f.write_str("N")?; + } else { + f.write_str("_")?; + } + + if self.h { + f.write_str("H")?; + } else { + f.write_str("_")?; + } + + if self.c { + f.write_str("C") + } else { + f.write_str("_") + } + } +} + impl From for Flags { fn from(flag: u8) -> Self { Self { diff --git a/src/high_ram.rs b/src/high_ram.rs new file mode 100644 index 0000000..a78c429 --- /dev/null +++ b/src/high_ram.rs @@ -0,0 +1,22 @@ +#[derive(Debug, Clone)] +pub struct HighRAM { + buf: Box<[u8]>, +} + +impl Default for HighRAM { + fn default() -> Self { + Self { + buf: vec![0u8; 127].into_boxed_slice(), + } + } +} + +impl HighRAM { + pub fn write_byte(&mut self, index: usize, byte: u8) { + self.buf[index] = byte; + } + + pub fn read_byte(&self, index: usize) -> u8 { + self.buf[index] + } +} diff --git a/src/instruction.rs b/src/instruction.rs index d84dfa8..989fb3b 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -1509,10 +1509,12 @@ impl Instruction { fn push(cpu: &mut Cpu, value: u16) { let mut sp = cpu.register_pair(RegisterPair::SP); + // FIXME: Are these debug functions really necessary? + sp -= 1; - cpu.write_byte(sp, (value >> 8) as u8); + cpu.dbg_write_byte(sp, (value >> 8) as u8); sp -= 1; - cpu.write_byte(sp, value as u8); + cpu.dbg_write_byte(sp, value as u8); cpu.set_register_pair(RegisterPair::SP, sp); } @@ -1523,9 +1525,11 @@ impl Instruction { fn pop(cpu: &mut Cpu) -> u16 { let mut sp = cpu.register_pair(RegisterPair::SP); - let low = cpu.read_byte(sp); + // FIXME: Are these debug functions really necessary? + + let low = cpu.dbg_read_byte(sp); sp += 1; - let high = cpu.read_byte(sp); + let high = cpu.dbg_read_byte(sp); sp += 1; cpu.set_register_pair(RegisterPair::SP, sp); diff --git a/src/lib.rs b/src/lib.rs index 4101db3..0183bf6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ mod bus; mod cartridge; pub mod cpu; +mod high_ram; mod instruction; mod interrupt; mod ppu; diff --git a/src/main.rs b/src/main.rs index 56ac559..17daecd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ fn main() { let instruction = game_boy.decode(opcode); println!( - "Addr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}", + "\nAddr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}", pc, opcode, instruction );