Skip to content

Commit

Permalink
Distinguish between gx fifo writes and normals writes in fastmem
Browse files Browse the repository at this point in the history
  • Loading branch information
Grarak committed Jan 31, 2025
1 parent ecacfdd commit 7981bd6
Show file tree
Hide file tree
Showing 16 changed files with 383 additions and 611 deletions.
255 changes: 0 additions & 255 deletions src/core/memory/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,227 +357,6 @@ impl<const CPU: CpuType, const TCM: bool, T: Convert> MemoryIo<CPU, TCM, T> {
fn write_gba(_: u32, _: T, _: &mut Emu) {}
}

struct MemoryReadMultipleIo<const CPU: CpuType, T: Convert, F: FnMut(T)> {
_data: PhantomData<T>,
_data1: PhantomData<F>,
}

impl<const CPU: CpuType, T: Convert, F: FnMut(T)> MemoryReadMultipleIo<CPU, T, F> {
const READ_LUT: [fn(u32, usize, F, &mut Emu); 16] = create_io_read_lut!();

fn read(addr: u32, size: usize, mut write_value: F, emu: &mut Emu) {
let read_shift = size_of::<T>() >> 1;
read_dtcm!(CPU, true, addr, emu, mem, shm_offset, {
for i in 0..size {
write_value(utils::read_from_mem(&mem.shm, shm_offset + (i << read_shift) as u32));
}
});
Self::READ_LUT[((addr >> 24) & 0xF) as usize](addr, size, write_value, emu)
}

fn read_itcm(addr: u32, size: usize, mut write_value: F, emu: &mut Emu) {
let read_shift = size_of::<T>() >> 1;
read_itcm!(
CPU,
true,
addr,
emu,
mem,
shm_offset,
{
for i in 0..size {
write_value(utils::read_from_mem(&mem.shm, shm_offset + (i << read_shift) as u32));
}
},
{
for _ in 0..size {
write_value(T::from(0));
}
}
);
}

fn read_main(addr: u32, size: usize, mut write_value: F, emu: &mut Emu) {
let read_shift = size_of::<T>() >> 1;
read_main!(addr, emu, mem, shm_offset, {
for i in 0..size {
write_value(utils::read_from_mem(&mem.shm, shm_offset + (i << read_shift) as u32));
}
});
}

fn read_wram(addr: u32, size: usize, mut write_value: F, emu: &mut Emu) {
let read_shift = size_of::<T>() >> 1;
read_wram!(CPU, addr, emu, mem, shm_offset, {
for i in 0..size {
write_value(utils::read_from_mem(&mem.shm, shm_offset + (i << read_shift) as u32));
}
});
}

fn read_io_ports(addr: u32, size: usize, mut write_value: F, emu: &mut Emu) {
let read_shift = size_of::<T>() >> 1;
read_io_ports!(
CPU,
addr,
emu,
mem,
addr_offset,
{
for i in 0..size {
match CPU {
ARM9 => write_value(mem.io_arm9.read(addr_offset + (i << read_shift) as u32, emu)),
ARM7 => write_value(mem.io_arm7.read(addr_offset + (i << read_shift) as u32, emu)),
}
}
},
{
for i in 0..size {
write_value(mem.wifi.read(addr_offset + (i << read_shift) as u32));
}
}
);
}

fn read_palettes(addr: u32, size: usize, mut write_value: F, emu: &mut Emu) {
let read_shift = size_of::<T>() >> 1;
let mem = get_mem!(emu);
for i in 0..size {
write_value(mem.palettes.read(addr + (i << read_shift) as u32));
}
}

fn read_vram(addr: u32, size: usize, mut write_value: F, emu: &mut Emu) {
let read_shift = size_of::<T>() >> 1;
let mem = get_mem!(emu);
for i in 0..size {
write_value(mem.vram.read::<CPU, _>(addr + (i << read_shift) as u32));
}
}

fn read_oam(addr: u32, size: usize, mut write_value: F, emu: &mut Emu) {
let read_shift = size_of::<T>() >> 1;
let mem = get_mem!(emu);
for i in 0..size {
write_value(mem.oam.read(addr + (i << read_shift) as u32));
}
}

fn read_gba(_: u32, size: usize, mut write_value: F, _: &mut Emu) {
for _ in 0..size {
write_value(T::from(0xFFFFFFFF));
}
}

fn read_invalid(_: u32, _: usize, _: F, _: &mut Emu) {
unsafe { unreachable_unchecked() }
}

fn read_bios(_: u32, size: usize, mut write_value: F, _: &mut Emu) {
for _ in 0..size {
write_value(T::from(0));
}
}
}

struct MemoryWriteMultipleIo<const CPU: CpuType, T: Convert, F: FnMut() -> T> {
_data: PhantomData<T>,
_data1: PhantomData<F>,
}

impl<const CPU: CpuType, T: Convert, F: FnMut() -> T> MemoryWriteMultipleIo<CPU, T, F> {
const WRITE_LUT: [fn(u32, usize, F, &mut Emu); 9] = create_io_write_lut!();

fn write(addr: u32, size: usize, mut read_value: F, emu: &mut Emu) {
let write_shift = size_of::<T>() >> 1;
write_dtcm!(CPU, true, addr, emu, mem, shm_offset, {
for i in 0..size {
utils::write_to_mem(&mut mem.shm, shm_offset + (i << write_shift) as u32, read_value())
}
});
let func = unsafe { Self::WRITE_LUT.get_unchecked(((addr >> 24) & 0xF) as usize) };
func(addr, size, read_value, emu);
}

fn write_itcm(addr: u32, size: usize, mut read_value: F, emu: &mut Emu) {
let write_shift = size_of::<T>() >> 1;
write_itcm!(CPU, true, addr, size << write_shift, emu, mem, shm_offset, {
for i in 0..size {
utils::write_to_mem(&mut mem.shm, shm_offset + (i << write_shift) as u32, read_value());
}
});
}

fn write_main(addr: u32, size: usize, mut read_value: F, emu: &mut Emu) {
let write_shift = size_of::<T>() >> 1;
write_main!(addr, size << write_shift, emu, mem, shm_offset, {
for i in 0..size {
utils::write_to_mem(&mut mem.shm, shm_offset + (i << write_shift) as u32, read_value());
}
});
}

fn write_wram(addr: u32, size: usize, mut read_value: F, emu: &mut Emu) {
let write_shift = size_of::<T>() >> 1;
write_wram!(CPU, addr, size << write_shift, emu, mem, shm_offset, {
for i in 0..size {
utils::write_to_mem(&mut mem.shm, shm_offset + (i << write_shift) as u32, read_value());
}
});
}

fn write_io_ports(addr: u32, size: usize, mut read_value: F, emu: &mut Emu) {
let write_shift = size_of::<T>() >> 1;
write_io_ports!(
CPU,
addr,
emu,
mem,
addr_offset,
{
for i in 0..size {
match CPU {
ARM9 => mem.io_arm9.write(addr_offset + (i << write_shift) as u32, read_value(), emu),
ARM7 => mem.io_arm7.write(addr_offset + (i << write_shift) as u32, read_value(), emu),
}
}
},
{
for i in 0..size {
mem.wifi.write(addr_offset + (i << write_shift) as u32, read_value());
}
}
)
}

fn write_palettes(addr: u32, size: usize, mut read_value: F, emu: &mut Emu) {
let write_shift = size_of::<T>() >> 1;
let mem = get_mem_mut!(emu);
for i in 0..size {
mem.palettes.write(addr + (i << write_shift) as u32, read_value());
}
}

fn write_vram(addr: u32, size: usize, mut read_value: F, emu: &mut Emu) {
let write_shift = size_of::<T>() >> 1;
let mem = get_mem_mut!(emu);
for i in 0..size {
mem.vram.write::<CPU, _>(addr + (i << write_shift) as u32, read_value());
}
mem.jit.invalidate_block(addr, size << write_shift);
}

fn write_oam(addr: u32, size: usize, mut read_value: F, emu: &mut Emu) {
let write_shift = size_of::<T>() >> 1;
let mem = get_mem_mut!(emu);
for i in 0..size {
mem.oam.write(addr + (i << write_shift) as u32, read_value());
}
}

fn write_gba(_: u32, _: usize, _: F, _: &mut Emu) {}
}

struct MemoryMultipleSliceIo<const CPU: CpuType, const TCM: bool, T: Convert> {
_data: PhantomData<T>,
}
Expand Down Expand Up @@ -1032,23 +811,6 @@ impl Memory {
ret
}

pub fn read_multiple<const CPU: CpuType, T: Convert, F: FnMut(T)>(&mut self, addr: u32, emu: &mut Emu, size: usize, mut write_value: F) {
debug_println!("{CPU:?} multiple memory read at {addr:x} with size {size}");
let aligned_addr = addr & !(size_of::<T>() as u32 - 1);
let aligned_addr = aligned_addr & 0x0FFFFFFF;

let shm_offset = self.get_shm_offset::<CPU, true, false>(aligned_addr) as u32;
if shm_offset != 0 {
let read_shift = size_of::<T>() >> 1;
for i in 0..size {
write_value(utils::read_from_mem(&self.shm, shm_offset + (i << read_shift) as u32));
}
return;
}

MemoryReadMultipleIo::<CPU, T, F>::read(aligned_addr, size, write_value, emu);
}

pub fn read_multiple_slice<const CPU: CpuType, const TCM: bool, T: Convert>(&mut self, addr: u32, emu: &mut Emu, slice: &mut [T]) {
debug_println!("{CPU:?} slice memory read at {addr:x} with size {}", size_of_val(slice));
let aligned_addr = addr & !(size_of::<T>() as u32 - 1);
Expand Down Expand Up @@ -1099,23 +861,6 @@ impl Memory {
MemoryIo::<CPU, TCM, T>::write(aligned_addr, value, emu);
}

pub fn write_multiple<const CPU: CpuType, T: Convert, F: FnMut() -> T>(&mut self, addr: u32, emu: &mut Emu, size: usize, mut read_value: F) {
debug_println!("{CPU:?} multiple memory write at {addr:x} with size {size}");
let aligned_addr = addr & !(size_of::<T>() as u32 - 1);
let aligned_addr = aligned_addr & 0x0FFFFFFF;

let shm_offset = self.get_shm_offset::<CPU, true, true>(aligned_addr) as u32;
if shm_offset != 0 {
let write_shift = size_of::<T>() >> 1;
for i in 0..size {
utils::write_to_mem(&mut self.shm, shm_offset + (i << write_shift) as u32, read_value());
}
return;
}

MemoryWriteMultipleIo::<CPU, T, F>::write(aligned_addr, size, read_value, emu);
}

pub fn write_multiple_slice<const CPU: CpuType, const TCM: bool, T: Convert>(&mut self, addr: u32, emu: &mut Emu, slice: &[T]) {
debug_println!("{CPU:?} fixed slice memory write at {addr:x} with size {}", slice.len());
let aligned_addr = addr & !(size_of::<T>() as u32 - 1);
Expand Down
2 changes: 1 addition & 1 deletion src/jit/assembler/arm/alu_assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ pub struct Ubfx {
impl Ubfx {
#[inline]
pub fn create(rd: Reg, rn: Reg, lsb: u8, width: u8, cond: Cond) -> u32 {
u32::from(crate::jit::assembler::arm::alu_assembler::Bfi::new(
u32::from(Ubfx::new(
u4::new(rn as u8),
u3::new(0b101),
u5::new(lsb),
Expand Down
Loading

0 comments on commit 7981bd6

Please sign in to comment.