Skip to content

Commit db1ab73

Browse files
committed
Implement fastmem for single read
1 parent ff6022c commit db1ab73

File tree

19 files changed

+806
-259
lines changed

19 files changed

+806
-259
lines changed

src/core/memory/mem.rs

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ use crate::core::cp15::TcmState;
22
use crate::core::emu::{get_cp15, Emu};
33
use crate::core::memory::io_arm7::IoArm7;
44
use crate::core::memory::io_arm9::IoArm9;
5-
use crate::core::memory::mmu::{MmuArm7, MmuArm9, MMU_PAGE_SHIFT};
5+
use crate::core::memory::mmu::{MmuArm7, MmuArm9, MMU_PAGE_SHIFT, MMU_PAGE_SIZE};
66
use crate::core::memory::oam::Oam;
77
use crate::core::memory::palettes::Palettes;
88
use crate::core::memory::regions;
99
use crate::core::memory::vram::Vram;
10+
use crate::core::memory::wifi::Wifi;
1011
use crate::core::memory::wram::Wram;
1112
use crate::core::spu::SoundSampler;
1213
use crate::core::CpuType;
@@ -15,8 +16,9 @@ use crate::jit::jit_memory::{JitMemory, JitRegion};
1516
use crate::logging::debug_println;
1617
use crate::mmap::Shm;
1718
use crate::utils::Convert;
19+
use crate::{utils, IS_DEBUG};
1820
use std::hint::unreachable_unchecked;
19-
use std::intrinsics::{likely, unlikely};
21+
use std::intrinsics::unlikely;
2022
use std::sync::atomic::AtomicU16;
2123
use std::sync::Arc;
2224
use CpuType::ARM7;
@@ -26,6 +28,7 @@ pub struct Memory {
2628
pub wram: Wram,
2729
pub io_arm7: IoArm7,
2830
pub io_arm9: IoArm9,
31+
pub wifi: Wifi,
2932
pub palettes: Palettes,
3033
pub vram: Vram,
3134
pub oam: Oam,
@@ -51,6 +54,7 @@ impl Memory {
5154
wram: Wram::new(),
5255
io_arm7: IoArm7::new(touch_points, sound_sampler),
5356
io_arm9: IoArm9::new(),
57+
wifi: Wifi::new(),
5458
palettes: Palettes::new(),
5559
vram: Vram::new(),
5660
oam: Oam::new(),
@@ -74,18 +78,19 @@ impl Memory {
7478
let aligned_addr = addr & !(size_of::<T>() as u32 - 1);
7579
let aligned_addr = aligned_addr & 0x0FFFFFFF;
7680

77-
let (vmem, mmu) = {
81+
let mmu = {
7882
let mmu = get_mem_mmu!(self, CPU);
7983
if CPU == ARM9 && TCM {
80-
(mmu.get_base_tcm_ptr(), mmu.get_mmu_read_tcm())
84+
mmu.get_mmu_read_tcm()
8185
} else {
82-
(mmu.get_base_ptr(), mmu.get_mmu_read())
86+
mmu.get_mmu_read()
8387
}
8488
};
8589

86-
let mapped = unsafe { *mmu.get_unchecked((aligned_addr as usize) >> MMU_PAGE_SHIFT) };
87-
if likely(mapped) {
88-
return unsafe { (vmem.add(aligned_addr as usize) as *const T).read() };
90+
let shm_offset = unsafe { *mmu.get_unchecked((aligned_addr as usize) >> MMU_PAGE_SHIFT) };
91+
if shm_offset != 0 {
92+
let offset = aligned_addr & (MMU_PAGE_SIZE as u32 - 1);
93+
return utils::read_from_mem(&self.shm, shm_offset as u32 + offset);
8994
}
9095

9196
let addr_base = aligned_addr & 0x0F000000;
@@ -99,7 +104,7 @@ impl Memory {
99104
if unlikely(addr_offset >= 0x800000) {
100105
let addr_offset = addr_offset & !0x8000;
101106
if unlikely(addr_offset >= 0x804000 && addr_offset < 0x806000) {
102-
unsafe { (vmem.add(aligned_addr as usize) as *const T).read() }
107+
self.wifi.read(addr_offset)
103108
} else {
104109
self.io_arm7.read(addr_offset, emu)
105110
}
@@ -111,7 +116,15 @@ impl Memory {
111116
regions::STANDARD_PALETTES_OFFSET => self.palettes.read(addr_offset),
112117
regions::VRAM_OFFSET => self.vram.read::<CPU, _>(addr_offset),
113118
regions::OAM_OFFSET => self.oam.read(addr_offset),
114-
_ => unsafe { unreachable_unchecked() },
119+
regions::GBA_ROM_OFFSET | regions::GBA_ROM_OFFSET2 | regions::GBA_RAM_OFFSET => T::from(0xFFFFFFFF),
120+
0x0F000000 => T::from(0),
121+
_ => {
122+
if IS_DEBUG {
123+
unreachable!("{CPU:?} {aligned_addr:x} tcm: {TCM}")
124+
} else {
125+
unsafe { unreachable_unchecked() }
126+
}
127+
}
115128
};
116129

117130
debug_println!("{:?} memory read at {:x} with value {:x}", CPU, addr, ret.into());
@@ -134,19 +147,45 @@ impl Memory {
134147
let addr_base = aligned_addr & 0x0F000000;
135148
let addr_offset = aligned_addr & !0xFF000000;
136149

137-
let vmem = {
138-
let mmu = get_mem_mmu!(self, CPU);
139-
if CPU == ARM9 && TCM {
140-
mmu.get_base_tcm_ptr()
141-
} else {
142-
mmu.get_base_ptr()
143-
}
144-
};
150+
// let mmu = {
151+
// let mmu = get_mem_mmu!(self, CPU);
152+
// if CPU == ARM9 && TCM {
153+
// mmu.get_mmu_write_tcm()
154+
// } else {
155+
// mmu.get_mmu_write()
156+
// }
157+
// };
158+
//
159+
// let shm_offset = unsafe { *mmu.get_unchecked((aligned_addr as usize) >> MMU_PAGE_SHIFT) };
160+
// if likely(shm_offset != 0) {
161+
// let offset = aligned_addr & (MMU_PAGE_SIZE as u32 - 1);
162+
// utils::write_to_mem(&mut self.shm, shm_offset as u32 + offset, value);
163+
// match CPU {
164+
// ARM9 => match addr_base {
165+
// regions::ITCM_OFFSET | regions::ITCM_OFFSET2 => self.jit.invalidate_block::<{ JitRegion::Itcm }>(aligned_addr, size_of::<T>()),
166+
// regions::MAIN_OFFSET => self.jit.invalidate_block::<{ JitRegion::Main }>(aligned_addr, size_of::<T>()),
167+
// _ => {}
168+
// },
169+
// ARM7 => match addr_base {
170+
// regions::MAIN_OFFSET => self.jit.invalidate_block::<{ JitRegion::Main }>(aligned_addr, size_of::<T>()),
171+
// regions::SHARED_WRAM_OFFSET => self.jit.invalidate_block::<{ JitRegion::Wram }>(aligned_addr, size_of::<T>()),
172+
// _ => {}
173+
// },
174+
// }
175+
// return;
176+
// }
177+
178+
macro_rules! write_to_shm {
179+
($shm_offset:expr, $addr_offset:expr, $size:expr) => {
180+
let offset = $addr_offset & ($size - 1);
181+
utils::write_to_mem(&mut self.shm, $shm_offset as u32 + offset, value);
182+
};
183+
}
145184

146185
if CPU == ARM9 && TCM {
147186
let cp15 = get_cp15!(emu, ARM9);
148187
if unlikely(aligned_addr >= cp15.dtcm_addr && aligned_addr < cp15.dtcm_addr + cp15.dtcm_size && cp15.dtcm_state != TcmState::Disabled) {
149-
unsafe { (vmem.add(aligned_addr as usize) as *mut T).write(value) }
188+
write_to_shm!(regions::DTCM_REGION.shm_offset, aligned_addr - cp15.dtcm_addr, regions::DTCM_SIZE);
150189
debug_println!("{:?} dtcm write at {:x} with value {:x}", CPU, aligned_addr, value.into(),);
151190
return;
152191
}
@@ -158,7 +197,7 @@ impl Memory {
158197
if TCM {
159198
let cp15 = get_cp15!(emu, ARM9);
160199
if aligned_addr < cp15.itcm_size && cp15.itcm_state != TcmState::Disabled {
161-
unsafe { (vmem.add(aligned_addr as usize) as *mut T).write(value) }
200+
write_to_shm!(regions::ITCM_REGION.shm_offset, addr_offset, regions::ITCM_SIZE);
162201
debug_println!("{:?} itcm write at {:x} with value {:x}", CPU, aligned_addr, value.into(),);
163202
self.jit.invalidate_block::<{ JitRegion::Itcm }>(aligned_addr, size_of::<T>());
164203
}
@@ -170,11 +209,12 @@ impl Memory {
170209
}
171210
},
172211
regions::MAIN_OFFSET => {
173-
unsafe { (vmem.add(aligned_addr as usize) as *mut T).write(value) };
212+
write_to_shm!(regions::MAIN_REGION.shm_offset, addr_offset, regions::MAIN_SIZE);
174213
self.jit.invalidate_block::<{ JitRegion::Main }>(aligned_addr, size_of::<T>());
175214
}
176215
regions::SHARED_WRAM_OFFSET => {
177-
unsafe { (vmem.add(aligned_addr as usize) as *mut T).write(value) };
216+
let shm_offset = self.wram.get_shm_offset::<CPU>(aligned_addr);
217+
write_to_shm!(shm_offset, 0, 1);
178218
if CPU == ARM7 {
179219
self.jit.invalidate_block::<{ JitRegion::Wram }>(aligned_addr, size_of::<T>());
180220
}
@@ -185,7 +225,7 @@ impl Memory {
185225
if unlikely(addr_offset >= 0x800000) {
186226
let addr_offset = addr_offset & !0x8000;
187227
if unlikely(addr_offset >= 0x804000 && addr_offset < 0x806000) {
188-
unsafe { (vmem.add(aligned_addr as usize) as *mut T).write(value) };
228+
self.wifi.write(addr_offset, value);
189229
} else {
190230
self.io_arm7.write(addr_offset, value, emu);
191231
}

0 commit comments

Comments
 (0)