Skip to content

Commit

Permalink
Make accessing emu components volatile
Browse files Browse the repository at this point in the history
* Minor refactoring
  • Loading branch information
Grarak committed Nov 3, 2024
1 parent d3824ef commit 9904662
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 56 deletions.
35 changes: 25 additions & 10 deletions src/core/emu.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
macro_rules! get_common {
($emu:expr) => {{
unsafe { $emu.common.get().as_ref().unwrap_unchecked() }
unsafe {
std::arch::asm!("");
$emu.common.get().as_ref_unchecked()
}
}};
}
pub(crate) use get_common;

macro_rules! get_common_mut {
($emu:expr) => {{
unsafe { $emu.common.get().as_mut().unwrap_unchecked() }
unsafe {
std::arch::asm!("");
$emu.common.get().as_mut_unchecked()
}
}};
}
pub(crate) use get_common_mut;

macro_rules! get_mem {
($emu:expr) => {{
unsafe { $emu.mem.get().as_ref().unwrap_unchecked() }
unsafe {
std::arch::asm!("");
$emu.mem.get().as_ref_unchecked()
}
}};
}
pub(crate) use get_mem;

macro_rules! get_mem_mut {
($emu:expr) => {{
unsafe { $emu.mem.get().as_mut().unwrap_unchecked() }
unsafe {
std::arch::asm!("");
$emu.mem.get().as_mut_unchecked()
}
}};
}
pub(crate) use get_mem_mut;
Expand Down Expand Up @@ -201,7 +213,10 @@ pub(crate) use get_ipc_mut;

macro_rules! get_arm7_hle_mut {
($emu:expr) => {{
unsafe { $emu.arm7_hle.get().as_mut().unwrap_unchecked() }
unsafe {
std::arch::asm!("");
$emu.arm7_hle.get().as_mut_unchecked()
}
}};
}
pub(crate) use get_arm7_hle_mut;
Expand Down Expand Up @@ -277,22 +292,22 @@ impl Emu {
}

pub fn mem_read<const CPU: CpuType, T: Convert>(&mut self, addr: u32) -> T {
unsafe { (*self.mem.get()).read::<CPU, T>(addr, self) }
unsafe { get_mem_mut!(self).read::<CPU, T>(addr, self) }
}

pub fn mem_read_no_tcm<const CPU: CpuType, T: Convert>(&mut self, addr: u32) -> T {
unsafe { (*self.mem.get()).read_no_tcm::<CPU, T>(addr, self) }
unsafe { get_mem_mut!(self).read_no_tcm::<CPU, T>(addr, self) }
}

pub fn mem_read_with_options<const CPU: CpuType, const TCM: bool, T: Convert>(&mut self, addr: u32) -> T {
unsafe { (*self.mem.get()).read_with_options::<CPU, TCM, T>(addr, self) }
unsafe { get_mem_mut!(self).read_with_options::<CPU, TCM, T>(addr, self) }
}

pub fn mem_write<const CPU: CpuType, T: Convert>(&mut self, addr: u32, value: T) {
unsafe { (*self.mem.get()).write::<CPU, T>(addr, value, self) };
unsafe { get_mem_mut!(self).write::<CPU, T>(addr, value, self) };
}

pub fn mem_write_no_tcm<const CPU: CpuType, T: Convert>(&mut self, addr: u32, value: T) {
unsafe { (*self.mem.get()).write_no_tcm::<CPU, T>(addr, value, self) };
unsafe { get_mem_mut!(self).write_no_tcm::<CPU, T>(addr, value, self) };
}
}
4 changes: 2 additions & 2 deletions src/core/hle/arm7_hle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl Arm7Hle {

let fifo = &mut get_ipc_mut!(emu).fifo[ARM7];
if fifo.queue.len() == 16 {
fifo.cnt.set_err(u1::new(1));
fifo.cnt.set_err(true);
} else {
fifo.queue.push_back(val);
if fifo.queue.len() == 1 {
Expand All @@ -51,7 +51,7 @@ impl Arm7Hle {

pub fn ipc_recv(&mut self, emu: &mut Emu) {
let val = get_ipc_mut!(emu).fifo[ARM9].queue.pop_front().unwrap();
if get_ipc!(emu).fifo[ARM9].queue.is_empty() && bool::from(get_ipc!(emu).fifo[ARM9].cnt.send_empty_irq()) {
if get_ipc!(emu).fifo[ARM9].queue.is_empty() && get_ipc!(emu).fifo[ARM9].cnt.send_empty_irq() {
get_cpu_regs_mut!(emu, ARM9).send_interrupt(InterruptFlag::IpcSendFifoEmpty, emu);
}

Expand Down
86 changes: 43 additions & 43 deletions src/core/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@ pub struct IpcSyncCnt {
pub data_out: u4,
// R/W
not_used1: u1,
pub send_irq: u1,
pub enable_irq: u1,
pub send_irq: bool,
pub enable_irq: bool,
// R/W
not_used2: u1,
}

#[bitsize(16)]
#[derive(Copy, Clone, FromBits)]
pub struct IpcFifoCnt {
pub send_empty_status: u1,
pub send_full_status: u1,
pub send_empty_status: bool,
pub send_full_status: bool,
pub send_empty_irq: bool,
pub send_clear: u1,
pub send_clear: bool,
not_used: u4,
pub recv_empty: u1,
pub recv_full: u1,
pub recv_not_empty_irq: u1,
pub recv_empty: bool,
pub recv_full: bool,
pub recv_not_empty_irq: bool,
not_used1: u3,
pub err: u1,
pub enable: u1,
pub err: bool,
pub enable: bool,
}

pub struct Fifo {
Expand Down Expand Up @@ -84,7 +84,7 @@ impl IpcInner for IpcLle {
get_ipc_mut!(emu).sync_regs[cpu] = ((u16::from(get_ipc!(emu).sync_regs[cpu]) & !mask) | (value & mask)).into();
get_ipc_mut!(emu).sync_regs[!cpu] = ((u16::from(get_ipc!(emu).sync_regs[!cpu]) & !((mask >> 8) & 0xF)) | (((value & mask) >> 8) & 0xF)).into();

if bool::from(IpcSyncCnt::from(value).send_irq()) && bool::from(get_ipc!(emu).sync_regs[!cpu].enable_irq()) {
if IpcSyncCnt::from(value).send_irq() && get_ipc!(emu).sync_regs[!cpu].enable_irq() {
get_cpu_regs_mut!(emu, !cpu).send_interrupt(InterruptFlag::IpcSync, emu);
}
}
Expand All @@ -96,18 +96,18 @@ impl IpcInner for IpcLle {
get_ipc_mut!(emu).fifo[cpu].queue.push_back(value & mask);

if fifo_len == 0 {
get_ipc_mut!(emu).fifo[cpu].cnt.set_send_empty_status(u1::new(0));
get_ipc_mut!(emu).fifo[!cpu].cnt.set_recv_empty(u1::new(0));
get_ipc_mut!(emu).fifo[cpu].cnt.set_send_empty_status(false);
get_ipc_mut!(emu).fifo[!cpu].cnt.set_recv_empty(false);

if bool::from(get_ipc!(emu).fifo[!cpu].cnt.recv_not_empty_irq()) {
if get_ipc!(emu).fifo[!cpu].cnt.recv_not_empty_irq() {
get_cpu_regs_mut!(emu, !cpu).send_interrupt(InterruptFlag::IpcRecvFifoNotEmpty, emu);
}
} else if fifo_len == 15 {
get_ipc_mut!(emu).fifo[cpu].cnt.set_send_full_status(u1::new(1));
get_ipc_mut!(emu).fifo[!cpu].cnt.set_recv_full(u1::new(1));
get_ipc_mut!(emu).fifo[cpu].cnt.set_send_full_status(true);
get_ipc_mut!(emu).fifo[!cpu].cnt.set_recv_full(true);
}
} else {
get_ipc_mut!(emu).fifo[cpu].cnt.set_err(u1::new(1));
get_ipc_mut!(emu).fifo[cpu].cnt.set_err(true);
}
}
}
Expand All @@ -125,22 +125,22 @@ impl IpcInner for IpcHle {
fn get_fifo_cnt(&self, _: CpuType, ipc: &Ipc) -> u16 {
let mut cnt = ipc.fifo[ARM9].cnt;

cnt.set_send_empty_status(u1::new(0));
cnt.set_send_full_status(u1::new(0));
cnt.set_recv_empty(u1::new(0));
cnt.set_recv_full(u1::new(0));
cnt.set_send_empty_status(false);
cnt.set_send_full_status(false);
cnt.set_recv_empty(false);
cnt.set_recv_full(false);

if ipc.fifo[ARM9].queue.is_empty() {
cnt.set_send_empty_status(u1::new(1));
cnt.set_send_empty_status(true);
} else if ipc.fifo[ARM9].queue.len() == 16 {
cnt.set_send_full_status(u1::new(1));
cnt.set_send_full_status(true);
}

cnt.set_send_empty_status(u1::new(1));
cnt.set_send_empty_status(true);
if ipc.fifo[ARM7].queue.is_empty() {
cnt.set_recv_empty(u1::new(1));
cnt.set_recv_empty(true);
} else if ipc.fifo[ARM7].queue.len() == 16 {
cnt.set_recv_full(u1::new(1));
cnt.set_recv_full(true);
}

cnt.into()
Expand All @@ -161,13 +161,13 @@ impl IpcInner for IpcHle {
get_ipc_mut!(emu).fifo[ARM9].queue.push_back(value & mask);

if fifo_len == 0 {
get_ipc_mut!(emu).fifo[ARM9].cnt.set_send_empty_status(u1::new(0));
get_ipc_mut!(emu).fifo[ARM9].cnt.set_send_empty_status(false);
} else if fifo_len == 15 {
get_ipc_mut!(emu).fifo[ARM9].cnt.set_send_full_status(u1::new(1));
get_ipc_mut!(emu).fifo[ARM9].cnt.set_send_full_status(true);
}
get_arm7_hle_mut!(emu).ipc_recv(emu);
} else {
get_ipc_mut!(emu).fifo[ARM9].cnt.set_err(u1::new(1));
get_ipc_mut!(emu).fifo[ARM9].cnt.set_err(true);
}
}
}
Expand Down Expand Up @@ -206,27 +206,27 @@ impl Ipc {
self.fifo[CPU].queue.clear();
self.fifo[CPU].last_received = 0;

self.fifo[CPU].cnt.set_send_empty_status(u1::new(1));
self.fifo[CPU].cnt.set_send_full_status(u1::new(0));
self.fifo[CPU].cnt.set_send_empty_status(true);
self.fifo[CPU].cnt.set_send_full_status(false);

self.fifo[!CPU].cnt.set_recv_empty(u1::new(1));
self.fifo[!CPU].cnt.set_recv_full(u1::new(0));
self.fifo[!CPU].cnt.set_recv_empty(true);
self.fifo[!CPU].cnt.set_recv_full(false);

if self.fifo[CPU].cnt.send_empty_irq() {
todo!()
}
}

if bool::from(self.fifo[CPU].cnt.send_empty_status()) && !bool::from(self.fifo[CPU].cnt.send_empty_irq()) && bool::from(new_fifo.send_empty_irq()) {
if bool::from(self.fifo[CPU].cnt.send_empty_status()) && !self.fifo[CPU].cnt.send_empty_irq() && new_fifo.send_empty_irq() {
get_cpu_regs_mut!(emu, CPU).send_interrupt(InterruptFlag::IpcSendFifoEmpty, emu);
}

if !bool::from(self.fifo[CPU].cnt.recv_empty()) && !bool::from(self.fifo[CPU].cnt.recv_not_empty_irq()) && bool::from(new_fifo.recv_not_empty_irq()) {
if !bool::from(self.fifo[CPU].cnt.recv_empty()) && !self.fifo[CPU].cnt.recv_not_empty_irq() && new_fifo.recv_not_empty_irq() {
get_cpu_regs_mut!(emu, CPU).send_interrupt(InterruptFlag::IpcRecvFifoNotEmpty, emu);
}

if bool::from(new_fifo.err()) {
self.fifo[CPU].cnt.set_err(u1::new(0));
self.fifo[CPU].cnt.set_err(false);
}

mask &= 0x8404;
Expand All @@ -242,23 +242,23 @@ impl Ipc {
if other_fifo_len > 0 {
self.fifo[CPU].last_received = *self.fifo[!CPU].queue.front().unwrap();

if bool::from(self.fifo[CPU].cnt.enable()) {
if self.fifo[CPU].cnt.enable() {
self.fifo[!CPU].queue.pop_front();

if other_fifo_len == 1 {
self.fifo[CPU].cnt.set_recv_empty(u1::new(1));
self.fifo[!CPU].cnt.set_send_empty_status(u1::new(1));
self.fifo[CPU].cnt.set_recv_empty(true);
self.fifo[!CPU].cnt.set_send_empty_status(true);

if bool::from(self.fifo[!CPU].cnt.send_empty_irq()) {
if self.fifo[!CPU].cnt.send_empty_irq() {
get_cpu_regs_mut!(emu, !CPU).send_interrupt(InterruptFlag::IpcSendFifoEmpty, emu);
}
} else if other_fifo_len == 16 {
self.fifo[CPU].cnt.set_recv_full(u1::new(0));
self.fifo[!CPU].cnt.set_send_full_status(u1::new(0));
self.fifo[CPU].cnt.set_recv_full(false);
self.fifo[!CPU].cnt.set_send_full_status(false);
}
}
} else {
self.fifo[CPU].cnt.set_err(u1::new(1));
self.fifo[CPU].cnt.set_err(true);
}

self.fifo[CPU].last_received
Expand Down
2 changes: 1 addition & 1 deletion src/core/memory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ pub mod oam;
pub mod palettes;
pub mod regions;
pub mod vram;
pub mod wram;
mod wifi;
pub mod wram;

0 comments on commit 9904662

Please sign in to comment.