diff --git a/Cargo.lock b/Cargo.lock index 9ed5941..ef0a2d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,22 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "arm7tdmi" +version = "0.1.0" +dependencies = [ + "ansi_term 0.12.1", + "bit", + "byteorder", + "cfg-if 1.0.0", + "colored", + "enum-primitive-derive", + "num 0.2.1", + "num-traits 0.2.12", + "rustboyadvance-utils", + "serde", +] + [[package]] name = "arrayref" version = "0.3.6" @@ -1351,6 +1367,7 @@ name = "rustboyadvance-core" version = "0.1.0" dependencies = [ "ansi_term 0.12.1", + "arm7tdmi", "arrayvec 0.5.2", "bincode", "bit", @@ -1371,14 +1388,13 @@ dependencies = [ "goblin", "hex-literal", "hexdump", - "instant", "lazy_static 1.4.0", "log 0.4.11", "memmem", "nom", "num 0.2.1", "num-traits 0.2.12", - "ringbuf", + "rustboyadvance-utils", "rustyline", "serde", "sha2", @@ -1433,11 +1449,20 @@ dependencies = [ "log 0.4.11", "ringbuf", "rustboyadvance-core", + "rustboyadvance-utils", "sdl2 0.33.0", "spin_sleep", "winres", ] +[[package]] +name = "rustboyadvance-utils" +version = "0.1.0" +dependencies = [ + "instant", + "ringbuf", +] + [[package]] name = "rustboyadvance-wasm" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index a9fe5ef..3319548 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,8 @@ [workspace] members = [ "core", + "arm7tdmi", + "utils", "platform/rustboyadvance-sdl2", "platform/rustboyadvance-libretro", "platform/rustboyadvance-minifb", diff --git a/arm7tdmi/Cargo.toml b/arm7tdmi/Cargo.toml new file mode 100644 index 0000000..5304536 --- /dev/null +++ b/arm7tdmi/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "arm7tdmi" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rustboyadvance-utils = {"path" = "../utils" } +bit = "^0.1" +cfg-if = "1.0.0" +serde = { version = "1.0.104", features = ["derive", "rc"] } +ansi_term = "0.12.1" +colored = "1.9" +byteorder = "1" +num = "0.2.1" +num-traits = "0.2" +enum-primitive-derive = "^0.1" + +[build-dependencies] +bit = "^0.1" \ No newline at end of file diff --git a/core/build.rs b/arm7tdmi/build.rs similarity index 97% rename from core/build.rs rename to arm7tdmi/build.rs index 3deefd8..d02b75c 100644 --- a/core/build.rs +++ b/arm7tdmi/build.rs @@ -1,3 +1,4 @@ +/// This build script creates ARM_LUT and THUMB_LUT opcode lookup table used cpu.rs use std::env; use std::fs; use std::io::Write; @@ -6,7 +7,7 @@ use std::path::Path; extern crate bit; use bit::BitIndex; -// copied and slightly adjusted from src/core/arm7tdmi/thumb/mod.rs +// copied and slightly adjusted from arm7tdmi/thumb/mod.rs fn thumb_decode(i: u16) -> (&'static str, String) { let offset5 = i.bit_range(6..11) as u8; let load = i.bit(11); @@ -180,7 +181,7 @@ trait BitAsInt>: BitIndex { impl BitAsInt for u32 {} -/// Returns a string representation of rustboyadvance_ng::core::arm7tdmi::arm::ArmFormat enum member +/// Returns a string representation of arm7tdmi::arm::ArmFormat enum member /// # Arguments /// * `i` - A 32bit ARM instruction /// @@ -368,7 +369,7 @@ fn arm_decode(i: u32) -> (&'static str, String) { } fn generate_thumb_lut(file: &mut fs::File) -> Result<(), std::io::Error> { - writeln!(file, "impl Core {{")?; + writeln!(file, "impl Arm7tdmiCore {{")?; writeln!( file, " pub const THUMB_LUT: [ThumbInstructionInfo; 1024] = [" @@ -380,7 +381,7 @@ fn generate_thumb_lut(file: &mut fs::File) -> Result<(), std::io::Error> { file, " /* {:#x} */ ThumbInstructionInfo {{ - handler_fn: Core::{}, + handler_fn: Arm7tdmiCore::{}, #[cfg(feature = \"debugger\")] fmt: ThumbFormat::{}, }},", @@ -395,7 +396,7 @@ fn generate_thumb_lut(file: &mut fs::File) -> Result<(), std::io::Error> { } fn generate_arm_lut(file: &mut fs::File) -> Result<(), std::io::Error> { - writeln!(file, "impl Core {{")?; + writeln!(file, "impl Arm7tdmiCore {{")?; writeln!( file, " pub const ARM_LUT: [ArmInstructionInfo; 4096] = [" @@ -406,7 +407,7 @@ fn generate_arm_lut(file: &mut fs::File) -> Result<(), std::io::Error> { file, " /* {:#x} */ ArmInstructionInfo {{ - handler_fn: Core::{}, + handler_fn: Arm7tdmiCore::{}, #[cfg(feature = \"debugger\")] fmt: ArmFormat::{}, }} ,", diff --git a/core/src/arm7tdmi/alu.rs b/arm7tdmi/src/alu.rs similarity index 98% rename from core/src/arm7tdmi/alu.rs rename to arm7tdmi/src/alu.rs index 52c124d..06c8e5d 100644 --- a/core/src/arm7tdmi/alu.rs +++ b/arm7tdmi/src/alu.rs @@ -1,7 +1,6 @@ use bit::BitIndex; -use super::memory::MemoryInterface; -use super::{Core, REG_PC}; +use crate::{memory::MemoryInterface, registers_consts::REG_PC, Arm7tdmiCore}; #[derive(Debug, Primitive, Eq, PartialEq)] pub enum AluOpCode { @@ -110,7 +109,7 @@ impl BarrelShifterValue { } } -impl Core { +impl Arm7tdmiCore { pub fn lsl(&mut self, val: u32, amount: u32, carry: &mut bool) -> u32 { match amount { 0 => val, diff --git a/core/src/arm7tdmi/arm/disass.rs b/arm7tdmi/src/arm/disass.rs similarity index 100% rename from core/src/arm7tdmi/arm/disass.rs rename to arm7tdmi/src/arm/disass.rs diff --git a/core/src/arm7tdmi/arm/exec.rs b/arm7tdmi/src/arm/exec.rs similarity index 98% rename from core/src/arm7tdmi/arm/exec.rs rename to arm7tdmi/src/arm/exec.rs index 885b55b..adf9d9f 100644 --- a/core/src/arm7tdmi/arm/exec.rs +++ b/arm7tdmi/src/arm/exec.rs @@ -1,17 +1,19 @@ use crate::bit::BitIndex; -use super::super::alu::*; -use crate::arm7tdmi::psr::RegPSR; -use crate::arm7tdmi::CpuAction; -use crate::arm7tdmi::{Addr, Core, CpuMode, CpuState, REG_LR, REG_PC}; +use crate::{ + alu::*, + memory::{MemoryAccess, MemoryInterface}, + psr::RegPSR, + registers_consts::{REG_LR, REG_PC}, + Arm7tdmiCore, CpuAction, CpuMode, CpuState, +}; -use super::super::memory::{MemoryAccess, MemoryInterface}; use MemoryAccess::*; use super::ArmDecodeHelper; use super::*; -impl Core { +impl Arm7tdmiCore { pub fn arm_undefined(&mut self, insn: u32) -> CpuAction { panic!( "executing undefined arm instruction {:08x} at @{:08x}", diff --git a/core/src/arm7tdmi/arm/mod.rs b/arm7tdmi/src/arm/mod.rs similarity index 99% rename from core/src/arm7tdmi/arm/mod.rs rename to arm7tdmi/src/arm/mod.rs index 745dc8d..f64540b 100644 --- a/core/src/arm7tdmi/arm/mod.rs +++ b/arm7tdmi/src/arm/mod.rs @@ -5,11 +5,12 @@ pub mod exec; use serde::{Deserialize, Serialize}; use super::alu::*; -use crate::arm7tdmi::{Addr, InstructionDecoder}; +use super::memory::Addr; +use super::InstructionDecoder; -use crate::bit::BitIndex; -use crate::byteorder::{LittleEndian, ReadBytesExt}; -use crate::num::FromPrimitive; +use bit::BitIndex; +use byteorder::{LittleEndian, ReadBytesExt}; +use num::FromPrimitive; use std::io; diff --git a/core/src/arm7tdmi/cpu.rs b/arm7tdmi/src/cpu.rs similarity index 96% rename from core/src/arm7tdmi/cpu.rs rename to arm7tdmi/src/cpu.rs index 8c8bcb3..d3a4eb7 100644 --- a/core/src/arm7tdmi/cpu.rs +++ b/arm7tdmi/src/cpu.rs @@ -4,7 +4,7 @@ pub use super::exception::Exception; use super::{arm::ArmCond, psr::RegPSR, Addr, CpuMode, CpuState}; -use crate::util::{Shared, WeakPointer}; +use rustboyadvance_utils::{Shared, WeakPointer}; use super::memory::{MemoryAccess, MemoryInterface}; use MemoryAccess::*; @@ -19,14 +19,14 @@ use super::arm::ArmFormat; #[cfg_attr(not(feature = "debugger"), repr(transparent))] pub struct ThumbInstructionInfo { - pub handler_fn: fn(&mut Core, insn: u16) -> CpuAction, + pub handler_fn: fn(&mut Arm7tdmiCore, insn: u16) -> CpuAction, #[cfg(feature = "debugger")] pub fmt: ThumbFormat, } #[cfg_attr(not(feature = "debugger"), repr(transparent))] pub struct ArmInstructionInfo { - pub handler_fn: fn(&mut Core, insn: u32) -> CpuAction, + pub handler_fn: fn(&mut Arm7tdmiCore, insn: u32) -> CpuAction, #[cfg(feature = "debugger")] pub fmt: ArmFormat, } @@ -104,7 +104,7 @@ impl Default for DebuggerState { } #[derive(Clone, Debug)] -pub struct Core { +pub struct Arm7tdmiCore { pub pc: u32, pub(super) bus: Shared, @@ -121,10 +121,10 @@ pub struct Core { pub dbg: DebuggerState, } -impl Core { - pub fn new(bus: Shared) -> Core { +impl Arm7tdmiCore { + pub fn new(bus: Shared) -> Arm7tdmiCore { let cpsr = RegPSR::new(0x0000_00D3); - Core { + Arm7tdmiCore { bus, pc: 0, gpr: [0; 15], @@ -139,12 +139,12 @@ impl Core { } } - pub fn weak_ptr(&mut self) -> WeakPointer> { - WeakPointer::new(self as *mut Core) + pub fn weak_ptr(&mut self) -> WeakPointer> { + WeakPointer::new(self as *mut Arm7tdmiCore) } - pub fn from_saved_state(bus: Shared, state: SavedCpuState) -> Core { - Core { + pub fn from_saved_state(bus: Shared, state: SavedCpuState) -> Arm7tdmiCore { + Arm7tdmiCore { bus, pc: state.pc, diff --git a/core/src/arm7tdmi/disass.rs b/arm7tdmi/src/disass.rs similarity index 100% rename from core/src/arm7tdmi/disass.rs rename to arm7tdmi/src/disass.rs diff --git a/core/src/arm7tdmi/exception.rs b/arm7tdmi/src/exception.rs similarity index 96% rename from core/src/arm7tdmi/exception.rs rename to arm7tdmi/src/exception.rs index 90d835c..2b2322a 100644 --- a/core/src/arm7tdmi/exception.rs +++ b/arm7tdmi/src/exception.rs @@ -1,5 +1,5 @@ -use super::cpu::Core; use super::memory::MemoryInterface; +use super::Arm7tdmiCore; use super::{CpuMode, CpuState}; #[derive(Debug, Clone, Copy, PartialEq)] @@ -16,7 +16,7 @@ pub enum Exception { Fiq = 0x1c, } -impl Core { +impl Arm7tdmiCore { pub fn exception(&mut self, e: Exception, lr: u32) { use Exception::*; let (new_mode, irq_disable, fiq_disable) = match e { diff --git a/core/src/arm7tdmi/mod.rs b/arm7tdmi/src/lib.rs similarity index 92% rename from core/src/arm7tdmi/mod.rs rename to arm7tdmi/src/lib.rs index 81d3297..90952fa 100644 --- a/core/src/arm7tdmi/mod.rs +++ b/arm7tdmi/src/lib.rs @@ -1,3 +1,12 @@ +#[macro_use] +extern crate serde; + +#[macro_use] +extern crate enum_primitive_derive; +use bit; +use num; +use num_traits; + use std::fmt; use num::Num; @@ -14,16 +23,17 @@ pub use cpu::*; pub mod alu; pub mod memory; pub use alu::*; +use memory::Addr; pub mod exception; pub mod psr; pub use psr::*; pub mod disass; -pub const REG_PC: usize = 15; -pub const REG_LR: usize = 14; -pub const REG_SP: usize = 13; - -pub(self) use crate::Addr; +pub mod registers_consts { + pub const REG_PC: usize = 15; + pub const REG_LR: usize = 14; + pub const REG_SP: usize = 13; +} #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum DecodedInstruction { diff --git a/core/src/arm7tdmi/memory.rs b/arm7tdmi/src/memory.rs similarity index 94% rename from core/src/arm7tdmi/memory.rs rename to arm7tdmi/src/memory.rs index cd14079..bcf9cc9 100644 --- a/core/src/arm7tdmi/memory.rs +++ b/arm7tdmi/src/memory.rs @@ -1,7 +1,8 @@ -use super::cpu::Core; -use super::Addr; +use super::Arm7tdmiCore; use std::fmt; +pub type Addr = u32; + #[derive(Serialize, Deserialize, Debug, Copy, Clone)] pub enum MemoryAccess { NonSeq = 0, @@ -35,7 +36,7 @@ pub enum MemoryAccessWidth { MemoryAccess32, } -/// A trait meant to abstract memory accesses and report the access type back to the user of the arm7tdmi::Core +/// A trait meant to abstract memory accesses and report the access type back to the user of the arm7tdmi::Arm7tdmiCore /// /// struct Memory { /// data: [u8; 0x4000] @@ -60,7 +61,7 @@ pub enum MemoryAccessWidth { /// } /// /// let mem = Shared::new(Memory { ... }); -/// let cpu = arm7tdmi::Core::new(mem.clone()) +/// let cpu = arm7tdmi::Arm7tdmiCore::new(mem.clone()) /// pub trait MemoryInterface { /// Read a byte @@ -80,7 +81,7 @@ pub trait MemoryInterface { fn idle_cycle(&mut self); } -impl MemoryInterface for Core { +impl MemoryInterface for Arm7tdmiCore { #[inline] fn load_8(&mut self, addr: u32, access: MemoryAccess) -> u8 { self.bus.load_8(addr, access) @@ -117,7 +118,7 @@ impl MemoryInterface for Core { } /// Implementation of memory access helpers -impl Core { +impl Arm7tdmiCore { #[inline] pub(super) fn store_aligned_32(&mut self, addr: Addr, value: u32, access: MemoryAccess) { self.store_32(addr & !0x3, value, access); diff --git a/core/src/arm7tdmi/psr.rs b/arm7tdmi/src/psr.rs similarity index 100% rename from core/src/arm7tdmi/psr.rs rename to arm7tdmi/src/psr.rs diff --git a/core/src/arm7tdmi/thumb/disass.rs b/arm7tdmi/src/thumb/disass.rs similarity index 100% rename from core/src/arm7tdmi/thumb/disass.rs rename to arm7tdmi/src/thumb/disass.rs diff --git a/core/src/arm7tdmi/thumb/exec.rs b/arm7tdmi/src/thumb/exec.rs similarity index 98% rename from core/src/arm7tdmi/thumb/exec.rs rename to arm7tdmi/src/thumb/exec.rs index d36f90a..33e8fca 100644 --- a/core/src/arm7tdmi/thumb/exec.rs +++ b/arm7tdmi/src/thumb/exec.rs @@ -1,13 +1,17 @@ -use crate::arm7tdmi::*; +use crate::{ + exception::Exception, + memory::{MemoryAccess, MemoryInterface}, + registers_consts::*, + Arm7tdmiCore, CpuAction, +}; -use crate::bit::BitIndex; +use bit::BitIndex; -use super::super::memory::{MemoryAccess, MemoryInterface}; use super::ThumbDecodeHelper; use super::*; use MemoryAccess::*; -impl Core { +impl Arm7tdmiCore { /// Format 1 /// Execution Time: 1S pub(in super::super) fn exec_thumb_move_shifted_reg( diff --git a/core/src/arm7tdmi/thumb/mod.rs b/arm7tdmi/src/thumb/mod.rs similarity index 98% rename from core/src/arm7tdmi/thumb/mod.rs rename to arm7tdmi/src/thumb/mod.rs index 7ace8c8..35bfc29 100644 --- a/core/src/arm7tdmi/thumb/mod.rs +++ b/arm7tdmi/src/thumb/mod.rs @@ -1,9 +1,10 @@ use super::alu::*; use super::arm::*; -use super::{Addr, InstructionDecoder}; -use crate::bit::BitIndex; -use crate::byteorder::{LittleEndian, ReadBytesExt}; -use crate::num::FromPrimitive; +use super::memory::Addr; +use super::InstructionDecoder; +use bit::BitIndex; +use byteorder::{LittleEndian, ReadBytesExt}; +use num::FromPrimitive; #[cfg(feature = "debugger")] pub mod disass; diff --git a/core/Cargo.toml b/core/Cargo.toml index 2c23504..6e4fe36 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -5,6 +5,8 @@ authors = ["Michel Heily "] edition = "2018" [dependencies] +arm7tdmi = { "path" = "../arm7tdmi" } +rustboyadvance-utils = { "path" = "../utils" } cfg-if = "1.0.0" serde = { version = "1.0.104", features = ["derive", "rc"] } bincode = "1.2.1" @@ -35,7 +37,6 @@ hex-literal = "0.2.1" rustyline = { version = "6.0.0", optional = true } nom = { version = "5.0.0", optional = true } gdbstub = { version = "0.1.2", optional = true, features = ["std"] } -ringbuf = "0.2.2" goblin = { version = "0.2", optional = true } fuzzy-matcher = { version = "0.3.4", optional = true } bit_reverse = "0.1.8" @@ -43,12 +44,6 @@ yaml-rust = "0.4" lazy_static = "1.4.0" smart-default = "0.6.0" -[target.'cfg(target_arch="wasm32")'.dependencies] -instant = { version = "0.1.2", features = ["wasm-bindgen"] } - -[build-dependencies] -bit = "^0.1" - [dev-dependencies] criterion = "0.3" diff --git a/core/src/bios.rs b/core/src/bios.rs index 022cfff..6fca0ff 100644 --- a/core/src/bios.rs +++ b/core/src/bios.rs @@ -1,7 +1,8 @@ -use super::arm7tdmi; -use super::bus::{Addr, Bus, DebugRead}; -use super::util::WeakPointer; +use super::bus::{Bus, DebugRead}; use super::SysBus; +use arm7tdmi::{memory::Addr, Arm7tdmiCore}; + +use rustboyadvance_utils::WeakPointer; /// Struct representing the sytem ROM #[derive(Clone)] @@ -11,7 +12,7 @@ pub struct Bios { /// Last read value last_opcode: u32, /// Arm pointer - used only to read the PC register - arm_core: WeakPointer>, + arm_core: WeakPointer>, } impl Bios { @@ -23,7 +24,7 @@ impl Bios { } } - pub(super) fn connect_arm_core(&mut self, arm_ptr: WeakPointer>) { + pub(super) fn connect_arm_core(&mut self, arm_ptr: WeakPointer>) { self.arm_core = arm_ptr; } diff --git a/core/src/bus.rs b/core/src/bus.rs index fd7ba7d..172dbcf 100644 --- a/core/src/bus.rs +++ b/core/src/bus.rs @@ -1,4 +1,4 @@ -pub type Addr = u32; +pub use arm7tdmi::memory::Addr; // re-export pub trait Bus { fn read_32(&mut self, addr: Addr) -> u32 { diff --git a/core/src/cartridge/backup/backup_file.rs b/core/src/cartridge/backup/backup_file.rs index 08c9a33..adfb320 100644 --- a/core/src/cartridge/backup/backup_file.rs +++ b/core/src/cartridge/backup/backup_file.rs @@ -8,7 +8,7 @@ use serde::de::{self, Deserialize, Deserializer, SeqAccess, Visitor}; use serde::ser::{Serialize, SerializeStruct, Serializer}; use super::BackupMemoryInterface; -use crate::util::write_bin_file; +use rustboyadvance_utils::write_bin_file; #[derive(Debug)] pub struct BackupFile { diff --git a/core/src/cartridge/loader.rs b/core/src/cartridge/loader.rs index 474bde5..69d3df5 100644 --- a/core/src/cartridge/loader.rs +++ b/core/src/cartridge/loader.rs @@ -6,7 +6,7 @@ use std::io::prelude::*; use std::io::Cursor; use std::path::Path; -use crate::util::read_bin_file; +use rustboyadvance_utils::read_bin_file; use zip::ZipArchive; #[cfg(feature = "elf_support")] diff --git a/core/src/debugger/command.rs b/core/src/debugger/command.rs index f53824c..be7fb97 100644 --- a/core/src/debugger/command.rs +++ b/core/src/debugger/command.rs @@ -7,7 +7,7 @@ use crate::arm7tdmi::thumb::ThumbInstruction; use crate::arm7tdmi::CpuState; use crate::bus::{Addr, Bus, DebugRead}; use crate::disass::Disassembler; -use crate::util::{read_bin_file, write_bin_file}; +use rustboyadvance_utils::{read_bin_file, write_bin_file}; // use super::palette_view::create_palette_view; // use super::tile_view::create_tile_view; diff --git a/core/src/gba.rs b/core/src/gba.rs index d46291c..f1fbdf3 100644 --- a/core/src/gba.rs +++ b/core/src/gba.rs @@ -5,7 +5,6 @@ use std::rc::Rc; use bincode; use serde::{Deserialize, Serialize}; -use super::arm7tdmi; use super::cartridge::Cartridge; use super::dma::DmaController; use super::gpu::*; @@ -15,14 +14,16 @@ use super::sched::{EventType, Scheduler, SchedulerConnect, SharedScheduler}; use super::sound::SoundController; use super::sysbus::SysBus; use super::timer::Timers; -use super::util::Shared; #[cfg(not(feature = "no_video_interface"))] use super::VideoInterface; use super::{AudioInterface, InputInterface}; +use arm7tdmi::{self, Arm7tdmiCore}; +use rustboyadvance_utils::Shared; + pub struct GameBoyAdvance { - pub cpu: Box>, + pub cpu: Box>, pub sysbus: Shared, pub io_devs: Shared, pub scheduler: SharedScheduler, @@ -103,7 +104,7 @@ impl GameBoyAdvance { gamepak, )); - let cpu = Box::new(arm7tdmi::Core::new(sysbus.clone())); + let cpu = Box::new(Arm7tdmiCore::new(sysbus.clone())); let mut gba = GameBoyAdvance { cpu, @@ -150,7 +151,7 @@ impl GameBoyAdvance { decoded.ewram, decoded.iwram, )); - let mut arm7tdmi = Box::new(arm7tdmi::Core::from_saved_state( + let mut arm7tdmi = Box::new(Arm7tdmiCore::from_saved_state( sysbus.clone(), decoded.cpu_state, )); diff --git a/core/src/gdb.rs b/core/src/gdb.rs index 4274d40..f0a1fd2 100644 --- a/core/src/gdb.rs +++ b/core/src/gdb.rs @@ -10,6 +10,44 @@ use gdbstub::{Access, Target, TargetState}; use std::io::Cursor; +use gdbstub; +use gdbstub::GdbStub; +use std::fmt; +use std::net::TcpListener; +use std::net::ToSocketAddrs; + +pub fn spawn_and_run_gdb_server( + #[allow(unused)] target: &mut GameBoyAdvance, + #[allow(unused)] addr: A, +) -> Result<(), Box> { + #[cfg(feature = "gdb")] + { + info!("spawning gdbserver, listening on {}", addr); + + let sock = TcpListener::bind(addr)?; + let (stream, addr) = sock.accept()?; + + info!("got connection from {}", addr); + + let mut gdb = GdbStub::new(stream); + let result = match gdb.run(target) { + Ok(state) => { + info!("Disconnected from GDB. Target state: {:?}", state); + Ok(()) + } + Err(gdbstub::Error::TargetError(e)) => Err(e), + Err(e) => return Err(e.into()), + }; + + info!("Debugger session ended, result={:?}", result); + } + #[cfg(not(feature = "gdb"))] + { + error!("failed. please compile me with 'gdb' feature") + } + + Ok(()) +} impl Target for GameBoyAdvance { type Usize = u32; type Error = (); diff --git a/core/src/gpu/mod.rs b/core/src/gpu/mod.rs index 1110695..36989cc 100644 --- a/core/src/gpu/mod.rs +++ b/core/src/gpu/mod.rs @@ -3,8 +3,11 @@ use std::cell::RefCell; #[cfg(not(feature = "no_video_interface"))] use std::rc::Rc; +use num::FromPrimitive; use serde::{Deserialize, Serialize}; +use rustboyadvance_utils::index2d; + use super::bus::*; use super::dma::{DmaNotifer, TIMING_HBLANK, TIMING_VBLANK}; use super::interrupt::{self, Interrupt, InterruptConnect, SharedInterruptFlags}; @@ -13,8 +16,6 @@ pub use super::sysbus::consts::*; #[cfg(not(feature = "no_video_interface"))] use super::VideoInterface; -use crate::num::FromPrimitive; - mod render; use render::Point; diff --git a/core/src/gpu/render/bitmap.rs b/core/src/gpu/render/bitmap.rs index 8b953b9..3ffc81e 100644 --- a/core/src/gpu/render/bitmap.rs +++ b/core/src/gpu/render/bitmap.rs @@ -7,6 +7,7 @@ use super::super::Rgb15; use super::{utils, MODE5_VIEWPORT, SCREEN_VIEWPORT}; use crate::Bus; +use rustboyadvance_utils::index2d; impl Gpu { pub(in super::super) fn render_mode3(&mut self, bg: usize) { diff --git a/core/src/gpu/render/obj.rs b/core/src/gpu/render/obj.rs index fe0595f..b76b6b7 100644 --- a/core/src/gpu/render/obj.rs +++ b/core/src/gpu/render/obj.rs @@ -1,6 +1,8 @@ use super::super::regs::*; use super::super::*; +use rustboyadvance_utils::index2d; + const OVRAM: u32 = 0x0601_0000; const PALRAM_OFS_FG: u32 = 0x200; const ATTRS_SIZE: u32 = 2 * 3 + 2; diff --git a/core/src/gpu/render/text.rs b/core/src/gpu/render/text.rs index a7e62a6..b90a6b0 100644 --- a/core/src/gpu/render/text.rs +++ b/core/src/gpu/render/text.rs @@ -7,6 +7,8 @@ use super::{utils, ViewPort}; use crate::Bus; +use rustboyadvance_utils::index2d; + impl Gpu { pub(in super::super) fn render_reg_bg(&mut self, bg: usize) { let (h_ofs, v_ofs) = (self.bg_hofs[bg] as u32, self.bg_vofs[bg] as u32); diff --git a/core/src/lib.rs b/core/src/lib.rs index d67b621..5f687f8 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -9,17 +9,13 @@ extern crate debug_stub_derive; #[macro_use] extern crate enum_primitive_derive; -use num; use num_traits; -use bit; #[macro_use] extern crate bitfield; #[macro_use] extern crate bitflags; -use byteorder; - #[macro_use] extern crate log; @@ -36,9 +32,7 @@ use zip; use std::error::Error; use std::fmt; -#[macro_use] -pub mod util; -pub mod arm7tdmi; +pub use arm7tdmi; pub use arm7tdmi::disass; mod bios; pub mod cartridge; @@ -140,10 +134,10 @@ pub mod prelude { #[cfg(feature = "debugger")] pub use super::debugger::Debugger; pub use super::gpu::{DISPLAY_HEIGHT, DISPLAY_WIDTH}; - pub use super::util::{read_bin_file, write_bin_file}; pub use super::Bus; #[cfg(not(feature = "no_video_interface"))] pub use super::VideoInterface; pub use super::{AudioInterface, InputInterface, StereoSample}; pub use super::{GBAError, GBAResult, GameBoyAdvance}; + pub use rustboyadvance_utils::{read_bin_file, write_bin_file}; } diff --git a/core/src/sched.rs b/core/src/sched.rs index 3464a3e..4ef031c 100644 --- a/core/src/sched.rs +++ b/core/src/sched.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; use std::collections::BinaryHeap; -use super::util::Shared; +use rustboyadvance_utils::Shared; use serde::{Deserialize, Serialize}; @@ -271,17 +271,19 @@ mod test { let mut sched = holder.sched.clone(); holder .sched - .push(EventType::Gpu(GpuEvent::VBlankHDraw), 240); + .schedule((EventType::Gpu(GpuEvent::VBlankHDraw), 240)); holder .sched - .push(EventType::Apu(ApuEvent::Psg1Generate), 60); - holder.sched.push(EventType::Apu(ApuEvent::Sample), 512); + .schedule((EventType::Apu(ApuEvent::Psg1Generate), 60)); holder .sched - .push(EventType::Apu(ApuEvent::Psg2Generate), 13); + .schedule((EventType::Apu(ApuEvent::Sample), 512)); holder .sched - .push(EventType::Apu(ApuEvent::Psg4Generate), 72); + .schedule((EventType::Apu(ApuEvent::Psg2Generate), 13)); + holder + .sched + .schedule((EventType::Apu(ApuEvent::Psg4Generate), 72)); assert_eq!( sched.events.pop(), @@ -300,17 +302,19 @@ mod test { let mut sched = holder.sched.clone(); holder .sched - .push(EventType::Gpu(GpuEvent::VBlankHDraw), 240); + .schedule((EventType::Gpu(GpuEvent::VBlankHDraw), 240)); holder .sched - .push(EventType::Apu(ApuEvent::Psg1Generate), 60); - holder.sched.push(EventType::Apu(ApuEvent::Sample), 512); + .schedule((EventType::Apu(ApuEvent::Psg1Generate), 60)); holder .sched - .push(EventType::Apu(ApuEvent::Psg2Generate), 13); + .schedule((EventType::Apu(ApuEvent::Sample), 512)); holder .sched - .push(EventType::Apu(ApuEvent::Psg4Generate), 72); + .schedule((EventType::Apu(ApuEvent::Psg2Generate), 13)); + holder + .sched + .schedule((EventType::Apu(ApuEvent::Psg4Generate), 72)); println!("all events"); for e in sched.events.iter() { diff --git a/core/src/sysbus.rs b/core/src/sysbus.rs index f0c3b6b..b4227f9 100644 --- a/core/src/sysbus.rs +++ b/core/src/sysbus.rs @@ -1,6 +1,5 @@ use serde::{Deserialize, Serialize}; -use super::arm7tdmi; use super::arm7tdmi::memory::*; use super::bios::Bios; use super::bus::*; @@ -8,7 +7,8 @@ use super::cartridge::Cartridge; use super::dma::DmaNotifer; use super::iodev::{IoDevices, WaitControl}; use super::sched::*; -use super::util::{Shared, WeakPointer}; +use arm7tdmi::{self, Arm7tdmiCore}; +use rustboyadvance_utils::{Shared, WeakPointer}; pub mod consts { pub const WORK_RAM_SIZE: usize = 256 * 1024; @@ -145,7 +145,7 @@ impl CycleLookupTables { pub struct SysBus { pub io: Shared, scheduler: Shared, - arm_core: WeakPointer>, + arm_core: WeakPointer>, bios: Bios, ewram: Box<[u8]>, @@ -225,7 +225,7 @@ impl SysBus { } /// must be called whenever this object is instanciated - pub fn init(&mut self, arm_core: WeakPointer>) { + pub fn init(&mut self, arm_core: WeakPointer>) { self.arm_core = arm_core.clone(); self.bios.connect_arm_core(arm_core.clone()); let ptr = SysBusPtr::new(self as *mut SysBus); @@ -268,10 +268,9 @@ impl SysBus { /// `addr` is considered to be an address of fn read_invalid(&mut self, addr: Addr) -> u32 { warn!("invalid read @{:08x}", addr); - use super::arm7tdmi::CpuState; let value = match self.arm_core.cpsr.state() { - CpuState::ARM => self.arm_core.get_prefetched_opcode(), - CpuState::THUMB => { + arm7tdmi::CpuState::ARM => self.arm_core.get_prefetched_opcode(), + arm7tdmi::CpuState::THUMB => { // For THUMB code the result consists of two 16bit fragments and depends on the address area // and alignment where the opcode was stored. diff --git a/platform/rustboyadvance-sdl2/Cargo.toml b/platform/rustboyadvance-sdl2/Cargo.toml index fe106e2..e3e6180 100644 --- a/platform/rustboyadvance-sdl2/Cargo.toml +++ b/platform/rustboyadvance-sdl2/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] rustboyadvance-core = { path = "../../core/", features = ["elf_support"] } +rustboyadvance-utils = { path = "../../utils/" } sdl2 = { version = "0.33.0", features = ["image"] } ringbuf = "0.2.2" bytesize = "1.0.0" diff --git a/platform/rustboyadvance-sdl2/src/main.rs b/platform/rustboyadvance-sdl2/src/main.rs index 3e19041..df17136 100644 --- a/platform/rustboyadvance-sdl2/src/main.rs +++ b/platform/rustboyadvance-sdl2/src/main.rs @@ -41,9 +41,11 @@ use input::create_input; use video::{create_video_interface, SCREEN_HEIGHT, SCREEN_WIDTH}; use rustboyadvance_core::cartridge::BackupType; +#[cfg(feature = "gdb")] +use rustboyadvance_core::gdb::spawn_and_run_gdb_server; use rustboyadvance_core::prelude::*; -use rustboyadvance_core::util::spawn_and_run_gdb_server; -use rustboyadvance_core::util::FpsCounter; + +use rustboyadvance_utils::FpsCounter; const LOG_DIR: &str = ".logs"; const DEFAULT_GDB_SERVER_ADDR: &'static str = "localhost:1337"; @@ -237,6 +239,7 @@ fn main() -> Result<(), Box> { } } + #[cfg(feature = "gdb")] if with_gdbserver { spawn_and_run_gdb_server(&mut gba, DEFAULT_GDB_SERVER_ADDR)?; } diff --git a/utils/Cargo.toml b/utils/Cargo.toml new file mode 100644 index 0000000..e046852 --- /dev/null +++ b/utils/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rustboyadvance-utils" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ringbuf = "0.2.2" + +[target.'cfg(target_arch="wasm32")'.dependencies] +instant = { version = "0.1.2", features = ["wasm-bindgen"] } diff --git a/core/src/util.rs b/utils/src/lib.rs similarity index 79% rename from core/src/util.rs rename to utils/src/lib.rs index 9f15b93..ab1747e 100644 --- a/core/src/util.rs +++ b/utils/src/lib.rs @@ -22,49 +22,6 @@ fn now() -> Instant { instant::Instant::now() } -use crate::GameBoyAdvance; -#[cfg(feature = "gdb")] -use gdbstub; -#[cfg(feature = "gdb")] -use gdbstub::GdbStub; -use std::fmt; -#[cfg(feature = "gdb")] -use std::net::TcpListener; -use std::net::ToSocketAddrs; - -pub fn spawn_and_run_gdb_server( - #[allow(unused)] target: &mut GameBoyAdvance, - #[allow(unused)] addr: A, -) -> Result<(), Box> { - #[cfg(feature = "gdb")] - { - info!("spawning gdbserver, listening on {}", addr); - - let sock = TcpListener::bind(addr)?; - let (stream, addr) = sock.accept()?; - - info!("got connection from {}", addr); - - let mut gdb = GdbStub::new(stream); - let result = match gdb.run(target) { - Ok(state) => { - info!("Disconnected from GDB. Target state: {:?}", state); - Ok(()) - } - Err(gdbstub::Error::TargetError(e)) => Err(e), - Err(e) => return Err(e.into()), - }; - - info!("Debugger session ended, result={:?}", result); - } - #[cfg(not(feature = "gdb"))] - { - error!("failed. please compile me with 'gdb' feature") - } - - Ok(()) -} - pub fn read_bin_file(filename: &Path) -> io::Result> { let mut buf = Vec::new(); let mut file = File::open(filename)?;