Add DebugRead trait

Former-commit-id: 4c9339dc0f2057152dcb6faccd78f058bc58676f
Former-commit-id: 7bf052ace6b5b12eca3c74f64f4d61d4ae6ac18e
This commit is contained in:
Michel Heily 2020-05-29 17:54:07 +03:00
parent b888fc0c95
commit 24f6ad61c1
7 changed files with 66 additions and 8 deletions

View file

@ -41,3 +41,24 @@ pub trait Bus {
bytes bytes
} }
} }
/// Helper trait for reading memory as if we were an all-powerfull debugger
pub trait DebugRead: Bus {
fn debug_read_32(&self, addr: Addr) -> u32 {
self.debug_read_16(addr) as u32 | (self.debug_read_16(addr + 2) as u32) << 16
}
fn debug_read_16(&self, addr: Addr) -> u16 {
self.debug_read_8(addr) as u16 | (self.debug_read_8(addr + 1) as u16) << 8
}
fn debug_read_8(&self, addr: Addr) -> u8;
fn debug_get_bytes(&self, range: std::ops::Range<u32>) -> Vec<u8> {
let mut bytes = Vec::new();
for b in range {
bytes.push(self.debug_read_8(b));
}
bytes
}
}

View file

@ -2,7 +2,7 @@ use std::collections::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::{Addr, Bus}; use super::bus::*;
pub mod header; pub mod header;
use header::CartridgeHeader; use header::CartridgeHeader;
@ -133,3 +133,10 @@ impl Bus for Cartridge {
self.default_write_16(addr, value); self.default_write_16(addr, value);
} }
} }
impl DebugRead for Cartridge {
fn debug_read_8(&self, addr: Addr) -> u8 {
let offset = (addr & 0x01ff_ffff) as usize;
self.bytes[offset]
}
}

View file

@ -4,9 +4,9 @@ use std::time;
use crate::arm7tdmi::arm::ArmInstruction; use crate::arm7tdmi::arm::ArmInstruction;
use crate::arm7tdmi::thumb::ThumbInstruction; use crate::arm7tdmi::thumb::ThumbInstruction;
use crate::arm7tdmi::CpuState; use crate::arm7tdmi::CpuState;
use crate::bus::{Addr, Bus, DebugRead};
use crate::disass::Disassembler; use crate::disass::Disassembler;
use crate::util::{read_bin_file, write_bin_file}; use crate::util::{read_bin_file, write_bin_file};
use crate::{Addr, Bus};
// use super::palette_view::create_palette_view; // use super::palette_view::create_palette_view;
// use super::tile_view::create_tile_view; // use super::tile_view::create_tile_view;
@ -135,7 +135,7 @@ impl Debugger {
println!("that took {:?} seconds", end - start); println!("that took {:?} seconds", end - start);
} }
HexDump(addr, nbytes) => { HexDump(addr, nbytes) => {
let bytes = self.gba.sysbus.get_bytes(addr..addr + nbytes); let bytes = self.gba.sysbus.debug_get_bytes(addr..addr + nbytes);
hexdump::hexdump(&bytes); hexdump::hexdump(&bytes);
} }
MemWrite(size, addr, val) => match size { MemWrite(size, addr, val) => match size {
@ -144,7 +144,7 @@ impl Debugger {
MemWriteCommandSize::Word => self.gba.sysbus.write_32(addr, val as u32), MemWriteCommandSize::Word => self.gba.sysbus.write_32(addr, val as u32),
}, },
Disass(mode, addr, n) => { Disass(mode, addr, n) => {
let bytes = self.gba.sysbus.get_bytes(addr..addr + n); let bytes = self.gba.sysbus.debug_get_bytes(addr..addr + n);
match mode { match mode {
DisassMode::ModeArm => { DisassMode::ModeArm => {
let disass = Disassembler::<ArmInstruction>::new(addr, &bytes); let disass = Disassembler::<ArmInstruction>::new(addr, &bytes);

View file

@ -4,12 +4,12 @@ use std::rc::Rc;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::bus::*;
use super::dma::{DmaNotifer, TIMING_HBLANK, TIMING_VBLANK}; use super::dma::{DmaNotifer, TIMING_HBLANK, TIMING_VBLANK};
use super::interrupt::{self, Interrupt, SharedInterruptFlags}; use super::interrupt::{self, Interrupt, SharedInterruptFlags};
pub use super::sysbus::consts::*; pub use super::sysbus::consts::*;
use super::util::BoxedMemory; use super::util::BoxedMemory;
use super::VideoInterface; use super::VideoInterface;
use super::{Addr, Bus};
use crate::bitfield::Bit; use crate::bitfield::Bit;
use crate::num::FromPrimitive; use crate::num::FromPrimitive;
@ -575,6 +575,18 @@ impl Bus for Gpu {
} }
} }
impl DebugRead for Gpu {
fn debug_read_8(&self, addr: Addr) -> u8 {
let page = (addr >> 24) as usize;
match page {
PAGE_PALRAM => self.palette_ram.read_8(addr),
PAGE_VRAM => self.vram.read_8(addr),
PAGE_OAM => self.vram.read_8(addr),
_ => unreachable!(),
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -1,5 +1,6 @@
use std::cmp; use std::cmp;
use super::bus::*;
use super::dma::DmaController; use super::dma::DmaController;
use super::gpu::regs::WindowFlags; use super::gpu::regs::WindowFlags;
use super::gpu::*; use super::gpu::*;
@ -8,7 +9,6 @@ use super::keypad;
use super::sound::SoundController; use super::sound::SoundController;
use super::sysbus::SysBusPtr; use super::sysbus::SysBusPtr;
use super::timer::Timers; use super::timer::Timers;
use super::{Addr, Bus};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -290,6 +290,12 @@ impl Bus for IoDevices {
} }
} }
impl DebugRead for IoDevices {
fn debug_read_8(&self, addr: Addr) -> u8 {
self.read_8(addr)
}
}
bitfield! { bitfield! {
#[derive(Serialize, Deserialize, Default, Copy, Clone, PartialEq)] #[derive(Serialize, Deserialize, Default, Copy, Clone, PartialEq)]
pub struct WaitControl(u16); pub struct WaitControl(u16);

View file

@ -2,10 +2,10 @@ use std::fmt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::bus::*;
use super::cartridge::Cartridge; use super::cartridge::Cartridge;
use super::dma::DmaNotifer; use super::dma::DmaNotifer;
use super::iodev::{IoDevices, WaitControl}; use super::iodev::{IoDevices, WaitControl};
use super::{Addr, Bus};
use super::util::{BoxedMemory, WeakPointer}; use super::util::{BoxedMemory, WeakPointer};
pub mod consts { pub mod consts {
@ -324,6 +324,12 @@ impl Bus for SysBus {
} }
} }
impl DebugRead for SysBus {
fn debug_read_8(&self, addr: Addr) -> u8 {
memory_map!(read(self, debug_read_8, addr, u8)) as u8
}
}
impl DmaNotifer for SysBus { impl DmaNotifer for SysBus {
fn notify(&mut self, timing: u16) { fn notify(&mut self, timing: u16) {
self.io.dmac.notify_from_gpu(timing); self.io.dmac.notify_from_gpu(timing);

View file

@ -6,7 +6,7 @@ use std::path::Path;
use std::ptr; use std::ptr;
use std::time; use std::time;
use super::bus::{Addr, Bus}; use super::bus::{Addr, Bus, DebugRead};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
type Instant = time::Instant; type Instant = time::Instant;
@ -216,3 +216,9 @@ impl Bus for BoxedMemory {
} }
} }
} }
impl DebugRead for BoxedMemory {
fn debug_read_8(&self, addr: Addr) -> u8 {
self.mem[addr as usize]
}
}