Add DebugRead trait
Former-commit-id: 4c9339dc0f2057152dcb6faccd78f058bc58676f Former-commit-id: 7bf052ace6b5b12eca3c74f64f4d61d4ae6ac18e
This commit is contained in:
parent
b888fc0c95
commit
24f6ad61c1
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in a new issue