Skip to content

Commit

Permalink
debugger architecture change and fix minor sla flag bug
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanballs committed Sep 11, 2024
1 parent 1553486 commit 1381aa4
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 32 deletions.
16 changes: 14 additions & 2 deletions src/cpu/execution/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ impl CPU {

pub(in crate::cpu) fn sla(&mut self, mmu: &mut MMU, reg: R8) {
let value = self.get_r8_byte(mmu, R8::A);
let new_value = (value << 1) | self.registers.f.carry as u8;
let new_value = value << 1;
self.set_r8_byte(mmu, reg, new_value);
self.registers.f.carry = value >> 7 == 1;

self.registers.f.carry = value & 0x80 == 0x80;
self.registers.f.half_carry = false;
self.registers.f.subtract = false;
self.registers.f.zero = new_value == 0;
Expand Down Expand Up @@ -101,6 +102,17 @@ impl CPU {
self.registers.f.carry = true;
}

pub(in crate::cpu) fn rr(&mut self, mmu: &mut MMU, r: R8) {
let old_carry = self.registers.f.carry;
let old_value = self.get_r8_byte(mmu, r);
let result = (old_value >> 1) | ((old_carry as u8) << 7);
self.registers.f.carry = old_value & 0x1 == 0x1;
self.registers.f.zero = result == 0;
self.registers.f.subtract = false;
self.registers.f.half_carry = false;
self.set_r8_byte(mmu, r, result);
}

pub(in crate::cpu) fn daa(&mut self) {
let mut correction = 0;
let mut set_carry = false;
Expand Down
8 changes: 4 additions & 4 deletions src/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use colored::*;
use registers::Registers;

use crate::{
debugger::enable_debug,
instructions::{parse, r16::R16, r8::R8, Instruction},
mmu::MMU,
};
Expand Down Expand Up @@ -83,6 +84,7 @@ impl CPU {
Instruction::Daa => self.daa(),
Instruction::SwapR8(reg) => self.swap(mmu, reg),
Instruction::Scf => self.scf(),
Instruction::RrR8(r) => self.rr(mmu, r),

// Jump instructions
Instruction::JpImm16(addr) => self.jp(addr.wrapping_sub(length)),
Expand Down Expand Up @@ -127,10 +129,8 @@ impl CPU {
get back out to the ranch and fix that dang emulator!"
.yellow()
);
dbg!(instruction);
dbg!(&self.registers);
dbg!(mmu.read_byte(self.registers.pc));
todo!();
enable_debug();
dbg!(self.registers.pc);
}
};

Expand Down
20 changes: 20 additions & 0 deletions src/debugger/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::sync::atomic::{AtomicBool, Ordering};

use crate::gameboy::GameBoy;
pub static DEBUG_MODE: AtomicBool = AtomicBool::new(false);

pub fn enable_debug() {
DEBUG_MODE.store(true, Ordering::SeqCst);
}

pub fn disable_debug() {
DEBUG_MODE.store(false, Ordering::SeqCst);
}

pub fn is_debug_enabled() -> bool {
DEBUG_MODE.load(Ordering::SeqCst)
}

pub fn debugger_cli(gameboy: &mut GameBoy) {
gameboy.debugger_cli();
}
18 changes: 15 additions & 3 deletions src/gameboy/debugger.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use core::fmt;
use std::io::{self, Write};

use crate::instructions::parse;
use crate::{
debugger::{disable_debug, enable_debug},
instructions::parse,
};

use super::GameBoy;
use colored::*;
Expand Down Expand Up @@ -34,12 +37,12 @@ impl GameBoy {

match command.as_str() {
"" | "s" | "step" => {
self.debugger_enabled = true;
enable_debug();
return;
}

"c" | "continue" => {
self.debugger_enabled = false;
disable_debug();
return;
}

Expand All @@ -63,6 +66,8 @@ impl GameBoy {

"i" | "interrupts" => self.print_interrupts(),

"ins" | "instructions" => self.print_instructions(),

"p" | "print" => self.print_memory_range(args),

"b" | "break" => {
Expand Down Expand Up @@ -173,6 +178,12 @@ impl GameBoy {
println!();
}

fn print_instructions(&self) {
for (addr, instruction) in self.instruction_history.iter() {
println!("{:#06X} {}", addr, instruction)
}
}

fn print_interrupts(&self) {
fn colored_bool(b: bool) -> String {
if b {
Expand Down Expand Up @@ -227,6 +238,7 @@ impl GameBoy {
println!("[i]nterrupts show interupt flags");
println!("[h]elp show this help info");
println!("[ro]m display gameboy rom");
println!("[ins]tructions last cpu operations");
println!("=============================================");
println!("");
}
Expand Down
16 changes: 11 additions & 5 deletions src/gameboy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ use std::collections::HashSet;
use crate::cpu::CPU;
use crate::instructions::{parse, Instruction};
use crate::mmu::MMU;
use std::collections::VecDeque;

pub struct GameBoy {
// debugger
pub debugger_enabled: bool,
breakpoints: HashSet<u16>,
memory_breakpoints: HashSet<u16>,
instruction_history: VecDeque<(u16, Instruction)>,

// state
pub mmu: MMU,
Expand All @@ -20,13 +21,12 @@ pub struct GameBoy {
impl GameBoy {
pub fn new(rom_data: Vec<u8>) -> GameBoy {
GameBoy {
debugger_enabled: false,
mmu: MMU::new(rom_data),
cpu: CPU::new(),

breakpoints: HashSet::with_capacity(10),
memory_breakpoints: HashSet::with_capacity(10),

mmu: MMU::new(rom_data),
cpu: CPU::new(),
instruction_history: VecDeque::with_capacity(10000),
}
}

Expand All @@ -35,6 +35,12 @@ impl GameBoy {
self.debugger_cli();
}

if self.instruction_history.len() == self.instruction_history.capacity() {
self.instruction_history.pop_front();
}
self.instruction_history
.push_back((self.cpu.registers.pc, self.ins()));

let _cycles = self.cpu.step(&mut self.mmu);
}

Expand Down
1 change: 1 addition & 0 deletions src/instructions/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ impl fmt::Display for Instruction {
"r16mem" => format!("{}", args.pop().unwrap()).blue().to_string(),
"imm8mem" => format!("[{}]", args.pop().unwrap()).blue().to_string(),
"imm16mem" => format!("[{}]", args.pop().unwrap()).blue().to_string(),
"cmem" => format!("[{}]", args.pop().unwrap()).blue().to_string(),
"tgt3" => format!("[{}]", args.pop().unwrap()).blue().to_string(),

"b3" => args.pop().unwrap().blue().to_string(),
Expand Down
22 changes: 9 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
pub mod cartridge;
pub mod cpu;
pub mod debugger;
pub mod gameboy;
pub mod instructions;
pub mod mmu;
mod renderer;

use cartridge::header::CartridgeHeader;
use colored::*;
use debugger::{enable_debug, is_debug_enabled};
use std::fs::File;
use std::io::Read;
use std::process::exit;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::AtomicBool;
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
use std::sync::{mpsc, Arc};
use std::thread;

use gameboy::GameBoy;
use minifb::Key;
use mmu::ppu::PPU;
use renderer::window_loop;

pub static DEBUG_MODE: AtomicBool = AtomicBool::new(false);

fn main() {
let (tx, rx) = mpsc::channel::<PPU>();
let (tx_key, rx_key) = mpsc::channel::<(bool, Key)>();
Expand All @@ -33,30 +37,22 @@ fn main() {
fn emulator_loop(rom: Vec<u8>, tx: Sender<PPU>, rx: Receiver<(bool, Key)>) {
let mut gameboy = GameBoy::new(rom);

let paused = Arc::new(AtomicBool::new(false));
let p = paused.clone();

ctrlc::set_handler(move || {
if p.load(Ordering::SeqCst) {
if is_debug_enabled() {
// If already paused, stop the emulator
println!("{}", "\nSo long space cowboy".red());
exit(-1);
} else {
// If running, pause the emulator
p.store(true, Ordering::SeqCst);
enable_debug();
println!("Received Ctrl+C! Pausing at the end of this step...");
}
})
.expect("Error setting Ctrl-C handler");

loop {
// Enter debug mode if Ctrl-C received
if paused.load(Ordering::SeqCst) {
gameboy.debugger_enabled = true;
}
paused.store(false, Ordering::SeqCst);

if gameboy.debugger_enabled {
if is_debug_enabled() {
gameboy.debugger_cli()
}

Expand Down
8 changes: 5 additions & 3 deletions src/mmu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ pub mod joypad;
pub mod ppu;
pub mod timer;

use crate::cartridge::Cartridge;
use crate::{cartridge::Cartridge, debugger::enable_debug};
use bootrom::BOOT_ROM;
use colored::Colorize;
use joypad::Joypad;
use ppu::PPU;
use timer::Timer;
Expand Down Expand Up @@ -58,8 +59,9 @@ impl MMU {

// Echo RAM
0xE000..=0xFDFF => {
println!("tried to read echo ram");
unreachable!()
println!("{}", "Tried to read ECHO ram".red());
enable_debug();
0x0
}

// Joypad
Expand Down
2 changes: 1 addition & 1 deletion src/mmu/ppu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl PPU {
0xFF40 => self.lcdc = value,
0xFF41 => self.stat = value,
0xFF42 => self.scy = value,
0xFF43 => self.scx = dbg!(value),
0xFF43 => self.scx = value,
0xFF45 => self.lyc = value,
0xFF47 => self.bgp = value,
0xFF48 => self.obj_palette_0 = value,
Expand Down
2 changes: 1 addition & 1 deletion src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub fn window_loop(rx: Receiver<PPU>, tx: Sender<(bool, Key)>, game_title: &Stri
render_tile(
&mut buffer,
ppu.get_tile(tile_index),
(ppu.scx as usize).wrapping_add(i as usize * 8) % 256,
(i as usize * 8).wrapping_sub(ppu.scx as usize) % 256,
((i as usize / 32) * 8).wrapping_sub(ppu.scy as usize),
0x0,
false,
Expand Down

0 comments on commit 1381aa4

Please sign in to comment.