chore: Refactor into crates

Been wanting to do this for a long time.
This does impose performance issues when building with the vanilla
release profile, as cargo does not perform optimizations across crate
boundary (we care mostly about inlining).
so I added release-lto profile

Also fixed some broken stuff I found across the project, meh


Former-commit-id: 06d03263cc6245313f3ea22c715479ab6da7c4d4
Former-commit-id: f93abd10c67ea8a3b8072b47462be5eca4f3e02b
This commit is contained in:
Michel Heily 2022-09-04 23:54:44 +03:00
parent 1535062e6c
commit 28fb9ffa70
36 changed files with 225 additions and 147 deletions

29
Cargo.lock generated
View file

@ -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"

View file

@ -1,6 +1,8 @@
[workspace]
members = [
"core",
"arm7tdmi",
"utils",
"platform/rustboyadvance-sdl2",
"platform/rustboyadvance-libretro",
"platform/rustboyadvance-minifb",

21
arm7tdmi/Cargo.toml Normal file
View file

@ -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"

View file

@ -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<T: From<bool>>: BitIndex {
impl BitAsInt<u32> 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<I: MemoryInterface> Core<I> {{")?;
writeln!(file, "impl<I: MemoryInterface> Arm7tdmiCore<I> {{")?;
writeln!(
file,
" pub const THUMB_LUT: [ThumbInstructionInfo<I>; 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<I: MemoryInterface> Core<I> {{")?;
writeln!(file, "impl<I: MemoryInterface> Arm7tdmiCore<I> {{")?;
writeln!(
file,
" pub const ARM_LUT: [ArmInstructionInfo<I>; 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::{},
}} ,",

View file

@ -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<I: MemoryInterface> Core<I> {
impl<I: MemoryInterface> Arm7tdmiCore<I> {
pub fn lsl(&mut self, val: u32, amount: u32, carry: &mut bool) -> u32 {
match amount {
0 => val,

View file

@ -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<I: MemoryInterface> Core<I> {
impl<I: MemoryInterface> Arm7tdmiCore<I> {
pub fn arm_undefined(&mut self, insn: u32) -> CpuAction {
panic!(
"executing undefined arm instruction {:08x} at @{:08x}",

View file

@ -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;

View file

@ -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<I: MemoryInterface> {
pub handler_fn: fn(&mut Core<I>, insn: u16) -> CpuAction,
pub handler_fn: fn(&mut Arm7tdmiCore<I>, insn: u16) -> CpuAction,
#[cfg(feature = "debugger")]
pub fmt: ThumbFormat,
}
#[cfg_attr(not(feature = "debugger"), repr(transparent))]
pub struct ArmInstructionInfo<I: MemoryInterface> {
pub handler_fn: fn(&mut Core<I>, insn: u32) -> CpuAction,
pub handler_fn: fn(&mut Arm7tdmiCore<I>, insn: u32) -> CpuAction,
#[cfg(feature = "debugger")]
pub fmt: ArmFormat,
}
@ -104,7 +104,7 @@ impl Default for DebuggerState {
}
#[derive(Clone, Debug)]
pub struct Core<I: MemoryInterface> {
pub struct Arm7tdmiCore<I: MemoryInterface> {
pub pc: u32,
pub(super) bus: Shared<I>,
@ -121,10 +121,10 @@ pub struct Core<I: MemoryInterface> {
pub dbg: DebuggerState,
}
impl<I: MemoryInterface> Core<I> {
pub fn new(bus: Shared<I>) -> Core<I> {
impl<I: MemoryInterface> Arm7tdmiCore<I> {
pub fn new(bus: Shared<I>) -> Arm7tdmiCore<I> {
let cpsr = RegPSR::new(0x0000_00D3);
Core {
Arm7tdmiCore {
bus,
pc: 0,
gpr: [0; 15],
@ -139,12 +139,12 @@ impl<I: MemoryInterface> Core<I> {
}
}
pub fn weak_ptr(&mut self) -> WeakPointer<Core<I>> {
WeakPointer::new(self as *mut Core<I>)
pub fn weak_ptr(&mut self) -> WeakPointer<Arm7tdmiCore<I>> {
WeakPointer::new(self as *mut Arm7tdmiCore<I>)
}
pub fn from_saved_state(bus: Shared<I>, state: SavedCpuState) -> Core<I> {
Core {
pub fn from_saved_state(bus: Shared<I>, state: SavedCpuState) -> Arm7tdmiCore<I> {
Arm7tdmiCore {
bus,
pc: state.pc,

View file

@ -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<I: MemoryInterface> Core<I> {
impl<I: MemoryInterface> Arm7tdmiCore<I> {
pub fn exception(&mut self, e: Exception, lr: u32) {
use Exception::*;
let (new_mode, irq_disable, fiq_disable) = match e {

View file

@ -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 mod registers_consts {
pub const REG_PC: usize = 15;
pub const REG_LR: usize = 14;
pub const REG_SP: usize = 13;
pub(self) use crate::Addr;
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum DecodedInstruction {

View file

@ -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<I: MemoryInterface> MemoryInterface for Core<I> {
impl<I: MemoryInterface> MemoryInterface for Arm7tdmiCore<I> {
#[inline]
fn load_8(&mut self, addr: u32, access: MemoryAccess) -> u8 {
self.bus.load_8(addr, access)
@ -117,7 +118,7 @@ impl<I: MemoryInterface> MemoryInterface for Core<I> {
}
/// Implementation of memory access helpers
impl<I: MemoryInterface> Core<I> {
impl<I: MemoryInterface> Arm7tdmiCore<I> {
#[inline]
pub(super) fn store_aligned_32(&mut self, addr: Addr, value: u32, access: MemoryAccess) {
self.store_32(addr & !0x3, value, access);

View file

@ -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<I: MemoryInterface> Core<I> {
impl<I: MemoryInterface> Arm7tdmiCore<I> {
/// Format 1
/// Execution Time: 1S
pub(in super::super) fn exec_thumb_move_shifted_reg<const BS_OP: u8, const IMM: u8>(

View file

@ -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;

View file

@ -5,6 +5,8 @@ authors = ["Michel Heily <michelheily@gmail.com>"]
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"

View file

@ -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<arm7tdmi::Core<SysBus>>,
arm_core: WeakPointer<Arm7tdmiCore<SysBus>>,
}
impl Bios {
@ -23,7 +24,7 @@ impl Bios {
}
}
pub(super) fn connect_arm_core(&mut self, arm_ptr: WeakPointer<arm7tdmi::Core<SysBus>>) {
pub(super) fn connect_arm_core(&mut self, arm_ptr: WeakPointer<Arm7tdmiCore<SysBus>>) {
self.arm_core = arm_ptr;
}

View file

@ -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 {

View file

@ -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 {

View file

@ -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")]

View file

@ -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;

View file

@ -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<arm7tdmi::Core<SysBus>>,
pub cpu: Box<Arm7tdmiCore<SysBus>>,
pub sysbus: Shared<SysBus>,
pub io_devs: Shared<IoDevices>,
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,
));

View file

@ -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<A: ToSocketAddrs + fmt::Display>(
#[allow(unused)] target: &mut GameBoyAdvance,
#[allow(unused)] addr: A,
) -> Result<(), Box<dyn std::error::Error>> {
#[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 = ();

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -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);

View file

@ -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};
}

View file

@ -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() {

View file

@ -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<IoDevices>,
scheduler: Shared<Scheduler>,
arm_core: WeakPointer<arm7tdmi::Core<SysBus>>,
arm_core: WeakPointer<Arm7tdmiCore<SysBus>>,
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<arm7tdmi::Core<SysBus>>) {
pub fn init(&mut self, arm_core: WeakPointer<Arm7tdmiCore<SysBus>>) {
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.

View file

@ -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"

View file

@ -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<dyn std::error::Error>> {
}
}
#[cfg(feature = "gdb")]
if with_gdbserver {
spawn_and_run_gdb_server(&mut gba, DEFAULT_GDB_SERVER_ADDR)?;
}

12
utils/Cargo.toml Normal file
View file

@ -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"] }

View file

@ -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<A: ToSocketAddrs + fmt::Display>(
#[allow(unused)] target: &mut GameBoyAdvance,
#[allow(unused)] addr: A,
) -> Result<(), Box<dyn std::error::Error>> {
#[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<Vec<u8>> {
let mut buf = Vec::new();
let mut file = File::open(filename)?;