Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugger #119

Merged
merged 40 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
0b99b2b
Add initial debugger support
alloncm Mar 21, 2023
4d99e19
Add support for registers command in the dbg
alloncm Mar 21, 2023
5776c7d
WIP Starting to add proper support for br
alloncm Mar 25, 2023
6df467c
Add delete BP command
alloncm Mar 31, 2023
6cbc1c1
Add gracefull error handling for channel close
alloncm Apr 1, 2023
eb51de3
Add the debbuger as conditional compile feature
alloncm Apr 1, 2023
a24c615
Add dbg feature to desktop
alloncm Apr 1, 2023
cb4a767
Add first memory view for the debugger
alloncm Apr 5, 2023
23d8b16
Rearrange packages and names
alloncm Jun 16, 2023
3db50e3
Update docs and readme
alloncm Jun 16, 2023
9e9c61e
Merge remote-tracking branch 'refs/remotes/origin/master'
alloncm Jun 16, 2023
e32adc6
Fix debugger gets stuck on invalid input
alloncm Jun 16, 2023
10f49cb
Add disassembler
alloncm Jun 17, 2023
88f0a83
Merge branch 'master' into feature/dbg
alloncm Jun 17, 2023
5a94e8f
Add memory watchpoint
alloncm Jun 17, 2023
40d00f1
watch point also on write
alloncm Jun 17, 2023
c7b6292
Adapt intergration tests for dbg feature
alloncm Jun 17, 2023
72a78ef
Create a seperate modle for the debugger in core
alloncm Jul 12, 2023
5fc7002
Fix compilation error
alloncm Jul 13, 2023
1e0d1d1
Fix breaking bug
alloncm Jul 13, 2023
6074d24
Move handle_debugger to debugger module
alloncm Jul 14, 2023
802d0e5
Fix stack overflow at init on debug builds
alloncm Jul 14, 2023
b204a3f
Add a help command
alloncm Jul 14, 2023
f1df905
Add ppu info command
alloncm Jul 15, 2023
6cf2c8d
Start to impl the ppu layer debugger
alloncm Jul 18, 2023
f304413
Merge branch 'master' into feature/dbg
alloncm Jun 22, 2024
d18286f
WIP continue impl of the bg layer view
alloncm Jun 22, 2024
ce820e6
Finish the bg layer view
alloncm Jul 19, 2024
9fb54a4
Add sprites layer viewer
alloncm Jul 20, 2024
dca30f1
Fix some sdl unsound usage and allowed the ppu layer windows to be cl…
alloncm Jul 20, 2024
a1489f6
Fixes
alloncm Jul 20, 2024
e6953ad
Fix the lag input in the menu
alloncm Jul 21, 2024
4cc8740
Self CR cleaning
alloncm Jul 21, 2024
33ba35d
More self CR fixes
alloncm Jul 21, 2024
afcdefd
More fixes and renames for the terminal debugger interface
alloncm Jul 21, 2024
47f99cd
Remove the use of global static in the terminal debugger
alloncm Jul 21, 2024
bbf8378
Add tests for the fixed size set
alloncm Jul 21, 2024
9cf3dd1
Add debugger docs
alloncm Jul 21, 2024
d984fad
Remove redundant note in the docs
alloncm Jul 21, 2024
175d6f9
Fix stack overflow on debugger enabled debug build
alloncm Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ or with more configuration options:
cargo build --release --package magenboy_sdl --features [optional_features]
```
#### Optional features:
* `dbg` - Enable debugger
* `static-sdl` - will link statically to sdl2, On by default
* `sdl-resample` - Use the audio resampler from sdl2 library and a manual one I wrote
* `push-audio` - Use a push methododlogy instead of pull for the delivery of the sound samples to sdl2
Expand Down
4 changes: 3 additions & 1 deletion common/src/joypad_menu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ impl<'a, T, S: AsRef<str>, MR:MenuRenderer<T, S>> JoypadMenu<'a, T, S, MR>{
}
}
}
// Busy wait untill A is released in order to not leak the button press to the emulation

// Busy wait until A is released in order to not leak the button press to the emulation
while joypad.buttons[Button::A as usize]{
provider.provide(&mut joypad);
}

return &self.options[self.selection].value;
}
}
2 changes: 2 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ edition.workspace = true

[dependencies]
log = "0.4"
cfg-if = "1"

[features]
u16pixel = []
apu = []
dbg = []

[dev-dependencies]
criterion = "0.3"
Expand Down
7 changes: 3 additions & 4 deletions core/src/cpu/gb_cpu.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::mmu::interrupts_handler::InterruptRequest;
use crate::mmu::memory::Memory;
use crate::mmu::{interrupts_handler::InterruptRequest, Memory};

use super::register::Reg;
use super::flag::Flag;
Expand Down Expand Up @@ -84,10 +83,10 @@ impl GbCpu {
}

pub fn inc_hl(&mut self){
*self.hl.value() = (*self.hl.value()).wrapping_add(1);
*self.hl.value_mut() = self.hl.value().wrapping_add(1);
}

pub fn dec_hl(&mut self){
*self.hl.value() = (*self.hl.value()).wrapping_sub(1);
*self.hl.value_mut() = self.hl.value().wrapping_sub(1);
}
}
2 changes: 1 addition & 1 deletion core/src/cpu/opcode_runner.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::mmu::memory::Memory;
use crate::mmu::Memory;
use super::{
gb_cpu::GbCpu,
opcodes::{
Expand Down
4 changes: 2 additions & 2 deletions core/src/cpu/opcodes/arithmetic_16bit_instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ use super::opcodes_utils::{
pub fn add_hl_rr(cpu:&mut GbCpu, opcode:u8)->u8{
let reg = opcode >> 4;
let reg = *get_arithmetic_16reg(cpu, reg);
let hl_value = *cpu.hl.value();
let hl_value = cpu.hl.value();

let (value,overflow) = hl_value.overflowing_add(reg);
cpu.set_by_value(Flag::Carry, overflow);
cpu.set_by_value(Flag::HalfCarry, check_for_half_carry_third_nible_add(hl_value, reg));
cpu.unset_flag(Flag::Subtraction);

*cpu.hl.value() = value;
*cpu.hl.value_mut() = value;

// 2 cycles - 1 reading opcode, 1 internal operation
return 1;
Expand Down
28 changes: 13 additions & 15 deletions core/src/cpu/opcodes/arithmetic_8bit_instructions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::cpu::gb_cpu::GbCpu;
use crate::cpu::flag::Flag;
use crate::mmu::memory::Memory;
use crate::{cpu::{gb_cpu::GbCpu, flag::Flag}, mmu::Memory};
use super::opcodes_utils::{
get_src_register,
check_for_half_carry_first_nible_add,
Expand Down Expand Up @@ -114,7 +112,7 @@ pub fn add_a_nn(cpu:&mut GbCpu, opcode:u16)->u8{

//add A and (hl)
pub fn add_a_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let src = memory.read(*cpu.hl.value(), 1);
let src = memory.read(cpu.hl.value(), 1);
let dest = *cpu.af.high();
*cpu.af.high() = add(cpu, dest, src);

Expand Down Expand Up @@ -144,7 +142,7 @@ pub fn adc_a_nn(cpu:&mut GbCpu, opcode:u16)->u8{

//add A and (hl) + Scarry
pub fn adc_a_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let src = memory.read(*cpu.hl.value(), 1);
let src = memory.read(cpu.hl.value(), 1);
let dest = *cpu.af.high();
*cpu.af.high() = adc(cpu, dest, src);

Expand Down Expand Up @@ -174,7 +172,7 @@ pub fn sub_a_nn(cpu:&mut GbCpu, opcode:u16)->u8{

//sub A and (hl)
pub fn sub_a_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let src = memory.read(*cpu.hl.value(), 1);
let src = memory.read(cpu.hl.value(), 1);
let dest = *cpu.af.high();
*cpu.af.high() = sub(cpu, dest, src);

Expand Down Expand Up @@ -205,7 +203,7 @@ pub fn sbc_a_nn(cpu:&mut GbCpu, opcode:u16)->u8{

//sub A and (hl)
pub fn sbc_a_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let src = memory.read(*cpu.hl.value(), 1);
let src = memory.read(cpu.hl.value(), 1);
let dest = *cpu.af.high();
*cpu.af.high() = subc(cpu, dest, src);

Expand Down Expand Up @@ -235,7 +233,7 @@ pub fn and_a_nn(cpu:&mut GbCpu, opcode:u16)->u8{

//and A and (hl)
pub fn and_a_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let src = memory.read(*cpu.hl.value(), 1);
let src = memory.read(cpu.hl.value(), 1);
let dest = *cpu.af.high();
*cpu.af.high() = and(cpu, dest, src);

Expand Down Expand Up @@ -265,7 +263,7 @@ pub fn xor_a_nn(cpu:&mut GbCpu, opcode:u16)->u8{

//xor A and (hl)
pub fn xor_a_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let src = memory.read(*cpu.hl.value(), 1);
let src = memory.read(cpu.hl.value(), 1);
let dest = *cpu.af.high();
*cpu.af.high() = xor(cpu, dest, src);

Expand Down Expand Up @@ -295,7 +293,7 @@ pub fn or_a_nn(cpu:&mut GbCpu, opcode:u16)->u8{

//or A and (hl)
pub fn or_a_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let src = memory.read(*cpu.hl.value(), 1);
let src = memory.read(cpu.hl.value(), 1);
let dest = *cpu.af.high();
*cpu.af.high() = or(cpu, dest, src);

Expand Down Expand Up @@ -325,7 +323,7 @@ pub fn cp_a_nn(cpu:&mut GbCpu, opcode:u16)->u8{

//or A and (hl)
pub fn cp_a_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let src = memory.read(*cpu.hl.value(), 1);
let src = memory.read(cpu.hl.value(), 1);
let dest = *cpu.af.high();
sub(cpu, dest, src);

Expand All @@ -351,9 +349,9 @@ pub fn inc_r(cpu:&mut GbCpu, opcode:u8)->u8{
}

pub fn inc_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let value = memory.read(*cpu.hl.value(), 1);
let value = memory.read(cpu.hl.value(), 1);
let altered_value = value.wrapping_add(1);
memory.write(*cpu.hl.value(), altered_value, 1);
memory.write(cpu.hl.value(), altered_value, 1);

cpu.set_by_value(Flag::Zero, altered_value == 0);
cpu.set_by_value(Flag::HalfCarry, check_for_half_carry_first_nible_add(value, 1));
Expand Down Expand Up @@ -381,9 +379,9 @@ pub fn dec_r(cpu:&mut GbCpu, opcode:u8)->u8{
}

pub fn dec_hl(cpu:&mut GbCpu, memory:&mut impl Memory)->u8{
let value = memory.read(*cpu.hl.value(), 1);
let value = memory.read(cpu.hl.value(), 1);
let altered_value = value.wrapping_sub(1);
memory.write(*cpu.hl.value(), altered_value, 1);
memory.write(cpu.hl.value(), altered_value, 1);

cpu.set_by_value(Flag::Zero, altered_value == 0);
cpu.set_by_value(Flag::HalfCarry, check_for_half_carry_first_nible_sub(value, altered_value));
Expand Down
2 changes: 1 addition & 1 deletion core/src/cpu/opcodes/cpu_control_instructions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{mmu::memory::Memory, cpu::{gb_cpu::GbCpu, flag::Flag}, utils::memory_registers::{IE_REGISTER_ADDRESS, JOYP_REGISTER_ADDRESS, KEY1_REGISTER_ADDRESS}};
use crate::{mmu::Memory, cpu::{gb_cpu::GbCpu, flag::Flag}, utils::memory_registers::{IE_REGISTER_ADDRESS, JOYP_REGISTER_ADDRESS, KEY1_REGISTER_ADDRESS}};

pub fn ccf(cpu:&mut GbCpu)->u8{
let carry:bool = cpu.get_flag(Flag::Carry);
Expand Down
11 changes: 3 additions & 8 deletions core/src/cpu/opcodes/jump_instructions.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
use crate::cpu::gb_cpu::GbCpu;
use crate::cpu::flag::Flag;
use crate::mmu::memory::Memory;
use super::opcodes_utils::{
pop,
push
};
use crate::{cpu::{gb_cpu::GbCpu, flag::Flag}, mmu::Memory};
use super::opcodes_utils::{pop,push};

fn push_pc(cpu:&mut GbCpu, memory: &mut impl Memory){
push(cpu, memory, cpu.program_counter);
Expand Down Expand Up @@ -134,7 +129,7 @@ pub fn jump_cc(cpu:&mut GbCpu, opcode:u32)->u8{
}

pub fn jump_hl(cpu:&mut GbCpu)->u8{
cpu.program_counter = *cpu.hl.value();
cpu.program_counter = cpu.hl.value();

// 1 cycles - 1 reading opcode
return 0;
Expand Down
18 changes: 8 additions & 10 deletions core/src/cpu/opcodes/load_16bit_instructions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::cpu::gb_cpu::GbCpu;
use crate::cpu::flag::Flag;
use crate::mmu::memory::Memory;
use crate::{cpu::{gb_cpu::GbCpu, flag::Flag}, mmu::Memory};
use super::opcodes_utils::{
get_arithmetic_16reg,
opcode_to_u16_value,
Expand All @@ -24,7 +22,7 @@ pub fn load_rr_nn(cpu:&mut GbCpu, opcode:u32)->u8{

//loads register HL into the SP
pub fn load_sp_hl(cpu:&mut GbCpu)->u8{
cpu.stack_pointer = *cpu.hl.value();
cpu.stack_pointer = cpu.hl.value();

// 2 cycles - 1 reading opcode, 1 internal operation
return 1;
Expand All @@ -42,7 +40,7 @@ pub fn pop(cpu:&mut GbCpu, memory:&mut impl Memory, opcode:u8)->u8{
_=>panic!("no register")
};

*reg.value() = poped_value;
*reg.value_mut() = poped_value;

// 3 cycles - 1 reading opcode, 2 reading sp address and sp+1 address
return 0;
Expand All @@ -52,10 +50,10 @@ pub fn pop(cpu:&mut GbCpu, memory:&mut impl Memory, opcode:u8)->u8{
pub fn push(cpu:&mut GbCpu, memory:&mut impl Memory, opcode:u8)->u8{
let reg = (opcode&0xF0)>>4;
let value = match reg{
0xC=>*cpu.bc.value(),
0xD=>*cpu.de.value(),
0xE=>*cpu.hl.value(),
0xF=>*cpu.af.value(),
0xC=>cpu.bc.value(),
0xD=>cpu.de.value(),
0xE=>cpu.hl.value(),
0xF=>cpu.af.value(),
_=>panic!("no register")
};

Expand All @@ -71,7 +69,7 @@ pub fn ld_hl_spdd(cpu:&mut GbCpu, opcode:u16)->u8{
let temp:i32 = cpu.stack_pointer as i32;
let value = temp.wrapping_add(dd as i32);

*cpu.hl.value() = value as u16;
*cpu.hl.value_mut() = value as u16;

//check for carry
cpu.set_by_value(Flag::Carry, signed_check_for_carry_first_nible_add(temp as i16, dd));
Expand Down
30 changes: 13 additions & 17 deletions core/src/cpu/opcodes/load_8bit_instructions.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
use crate::cpu::gb_cpu::GbCpu;
use crate::mmu::memory::Memory;
use super::opcodes_utils::{
get_src_register,
get_reg_two_rows
};
use crate::{cpu::gb_cpu::GbCpu, mmu::Memory};
use super::opcodes_utils::{get_src_register, get_reg_two_rows};

const IO_PORTS_ADDRESS:u16 = 0xFF00;

Expand Down Expand Up @@ -46,7 +42,7 @@ pub fn ld_r_n(cpu: &mut GbCpu, opcode:u16)->u8 {
//load the value in address of HL into dest register
pub fn ld_r_hl(cpu:&mut GbCpu, memory:&mut impl Memory, opcode:u8)->u8{
let reg = opcode>>3;
let hl_value = *cpu.hl.value();
let hl_value = cpu.hl.value();
let reg = match reg{
0x8=>cpu.bc.high(),
0x9=>cpu.bc.low(),
Expand All @@ -66,7 +62,7 @@ pub fn ld_r_hl(cpu:&mut GbCpu, memory:&mut impl Memory, opcode:u8)->u8{

//load the value in reg_src into the address of HL in memory
pub fn ld_hl_r(cpu:&mut GbCpu, memory:&mut impl Memory, opcode:u8)->u8{
memory.write(*cpu.hl.value(), *get_src_register(cpu, opcode), 1);
memory.write(cpu.hl.value(), *get_src_register(cpu, opcode), 1);

// 2 cycles, 1 reading opcode, 1 writing hl address
return 0;
Expand All @@ -75,23 +71,23 @@ pub fn ld_hl_r(cpu:&mut GbCpu, memory:&mut impl Memory, opcode:u8)->u8{
//load the valie src into the address HL in memory
pub fn ld_hl_n(cpu: &mut GbCpu, memory:&mut impl Memory, opcode:u16)->u8{
let src = (0xFF & opcode) as u8;
memory.write(*cpu.hl.value(), src, 1);
memory.write(cpu.hl.value(), src, 1);

// 3 cycles - 2 reading opcode, 1 writing hl address
return 0;
}

//load the value in address of BC into register A
pub fn ld_a_bc(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{
*cpu.af.high() = memory.read(*cpu.bc.value(), 1);
*cpu.af.high() = memory.read(cpu.bc.value(), 1);

// 2 cycles - 1 reading opcode, 1 reading bc address
return 0;
}

//load the value in address of DE into register A
pub fn ld_a_de(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{
*cpu.af.high() = memory.read(*cpu.de.value(), 1);
*cpu.af.high() = memory.read(cpu.de.value(), 1);

// 2 cycles - 1 reading opcode, 1 reading de address
return 0;
Expand All @@ -109,15 +105,15 @@ pub fn ld_a_nn(cpu: &mut GbCpu, memory:&mut impl Memory, opcode:u32)->u8{

//load the value in register A into the address of BC
pub fn ld_bc_a(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{
memory.write(*cpu.bc.value(), *cpu.af.high(), 1);
memory.write(cpu.bc.value(), *cpu.af.high(), 1);

// 2 cycles - 1 reading opcode, 1 writing bc address
return 0;
}

//load the value in register A into the address of DE
pub fn ld_de_a(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{
memory.write(*cpu.de.value(), *cpu.af.high(), 1);
memory.write(cpu.de.value(), *cpu.af.high(), 1);

// 2 cycles - 1 reading opcode, 1 writing de address
return 0;
Expand All @@ -135,7 +131,7 @@ pub fn ld_nn_a(cpu: &mut GbCpu, memory:&mut impl Memory, opcode:u32)->u8{

//load value in register A into address HL and then increment register HL value
pub fn ldi_hl_a(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{
memory.write(*cpu.hl.value(), *cpu.af.high(), 1);
memory.write(cpu.hl.value(), *cpu.af.high(), 1);
cpu.inc_hl();

// 2 cycles - 1 reading opcode, 1 writing hl address
Expand All @@ -144,7 +140,7 @@ pub fn ldi_hl_a(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{

//load into register A the value in address HL and then increment register HL value
pub fn ldi_a_hl(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{
*cpu.af.high() = memory.read(*cpu.hl.value(), 1);
*cpu.af.high() = memory.read(cpu.hl.value(), 1);
cpu.inc_hl();

// 2 cycles - 1 reading opcode, 1 reading hl address
Expand All @@ -153,7 +149,7 @@ pub fn ldi_a_hl(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{

//load value in register A into address HL and then decrement register HL value
pub fn ldd_hl_a(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{
memory.write(*cpu.hl.value(), *cpu.af.high(), 1);
memory.write(cpu.hl.value(), *cpu.af.high(), 1);
cpu.dec_hl();

// 2 cycles - 1 reading opcode, 1 writing hl address
Expand All @@ -162,7 +158,7 @@ pub fn ldd_hl_a(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{

//load into register A the value in address HL and then decrement register HL value
pub fn ldd_a_hl(cpu: &mut GbCpu, memory:&mut impl Memory)->u8{
*cpu.af.high() = memory.read(*cpu.hl.value(), 1);
*cpu.af.high() = memory.read(cpu.hl.value(), 1);
cpu.dec_hl();

// 2 cycles - 1 reading opcode, 1 reading hl address
Expand Down
Loading
Loading