diff --git a/src/bios.rs b/src/bios.rs index 29c518f2..08a8d39d 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -11,6 +11,8 @@ #[allow(unused)] use crate::prelude::*; +use core::arch::asm; + /// (`swi 0x00`) Performs a "soft reset" of the device. /// /// Loads `r14` based on the `u8` value at `0x0300_7FFA`: diff --git a/src/lib.rs b/src/lib.rs index 40087efc..16a7ffae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![feature(asm, global_asm, isa_attribute)] +#![feature(isa_attribute)] //! This crate helps you write GBA ROMs. //! @@ -31,11 +31,11 @@ pub mod prelude { #[cfg(target_arch = "arm")] pub use crate::mmio_addresses::*; #[cfg(target_arch = "arm")] + pub use crate::random::*; + #[cfg(target_arch = "arm")] pub use crate::save::*; #[cfg(target_arch = "arm")] pub use crate::sync::*; - #[cfg(target_arch = "arm")] - pub use crate::random::*; } pub mod mmio_types; diff --git a/src/mmio_addresses/mode3.rs b/src/mmio_addresses/mode3.rs index 75460ff5..a0255de9 100644 --- a/src/mmio_addresses/mode3.rs +++ b/src/mmio_addresses/mode3.rs @@ -1,5 +1,6 @@ use crate::prelude::Color; +use core::arch::asm; use voladdress::*; pub const WIDTH: usize = 240; diff --git a/src/save/asm_utils.rs b/src/save/asm_utils.rs index e9051ee5..13997e82 100644 --- a/src/save/asm_utils.rs +++ b/src/save/asm_utils.rs @@ -2,8 +2,9 @@ //! WRAM. Both flash media and battery-backed SRAM require reads to be //! performed via code in WRAM and cannot be accessed by DMA. -#![cfg_attr(not(target_arch = "arm"), allow(unused_variables, non_snake_case))] +use core::arch::global_asm; +#[cfg_attr(not(target_arch = "arm"), allow(unused_variables, non_snake_case))] #[cfg(target_arch = "arm")] global_asm!(include_str!("asm_routines.s")); diff --git a/src/sync.rs b/src/sync.rs index 3e170605..263e0ef0 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -2,6 +2,8 @@ use crate::prelude::*; +use core::arch::asm; + mod locks; mod statics; diff --git a/src/sync/statics.rs b/src/sync/statics.rs index 8b8ed55f..db09d78c 100644 --- a/src/sync/statics.rs +++ b/src/sync/statics.rs @@ -2,6 +2,7 @@ use crate::sync::with_irqs_disabled; use core::{ + arch::asm, cell::UnsafeCell, mem::{align_of, size_of, MaybeUninit}, ptr, @@ -20,8 +21,10 @@ unsafe fn transfer(dst: *mut T, src: *const T) { // We can do an 4-byte aligned transfer up to 16 bytes. transfer_align4_thumb(dst, src); } else if size <= 36 && align % 4 == 0 { - // We can do the same up to 36 bytes, but we need to switch to ARM. - transfer_align4_arm(dst, src); + // // We can do the same up to 36 bytes, but we need to switch to ARM. + // transfer_align4_arm(dst, src); + // TODO(rust-console/gba#158) Cannot optimize larger transfers for now. + with_irqs_disabled(|| ptr::write_volatile(dst, ptr::read_volatile(src))); } else if size <= 2 && align % 2 == 0 { // We can do a 2-byte aligned transfer up to 2 bytes. asm!( @@ -82,65 +85,66 @@ unsafe fn transfer_align4_thumb(mut dst: *mut T, mut src: *const T) { } } -#[cfg(target_arch = "arm")] -#[instruction_set(arm::a32)] -#[allow(unused_assignments)] -unsafe fn transfer_align4_arm(mut dst: *mut T, mut src: *const T) { - let size = size_of::(); - if size <= 16 { - unimplemented!("This should be done via transfer_thumb."); - } else if size <= 20 { - // Starting at size == 20, we have to switch to ARM due to lack of - // accessible registers in THUMB mode. - asm!( - "ldmia {0}!, {{r2-r5,r8}}", - "stmia {1}!, {{r2-r5,r8}}", - inout(reg) src, inout(reg) dst, - out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, - ) - } else if size <= 24 { - asm!( - "push {{r9}}", - "ldmia {0}!, {{r2-r5,r8-r9}}", - "stmia {1}!, {{r2-r5,r8-r9}}", - "pop {{r9}}", - inout(reg) src, inout(reg) dst, - out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, - ) - } else if size <= 28 { - asm!( - "push {{r9}}", - "ldmia {0}!, {{r2-r5,r8-r10}}", - "stmia {1}!, {{r2-r5,r8-r10}}", - "pop {{r9}}", - inout(reg) src, inout(reg) dst, - out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, - out("r10") _, - ) - } else if size <= 32 { - asm!( - "push {{r9}}", - "ldmia {0}!, {{r2-r5,r8-r10,r12}}", - "stmia {1}!, {{r2-r5,r8-r10,r12}}", - "pop {{r9}}", - inout(reg) src, inout(reg) dst, - out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, - out("r10") _, out("r12") _, - ) - } else if size <= 36 { - asm!( - "push {{r9}}", - "ldmia {0}!, {{r2-r5,r8-r10,r12,r14}}", - "stmia {1}!, {{r2-r5,r8-r10,r12,r14}}", - "pop {{r9}}", - inout(reg) src, inout(reg) dst, - out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, - out("r10") _, out("r12") _, out("r14") _, - ) - } else { - unimplemented!("Copy too large for use of ldmia/stmia."); - } -} +// TODO(rust-console/gba#158) Un-comment out this fn when we can use higher registers. +// #[cfg(target_arch = "arm")] +// #[instruction_set(arm::a32)] +// #[allow(unused_assignments)] +// unsafe fn transfer_align4_arm(mut dst: *mut T, mut src: *const T) { +// let size = size_of::(); +// if size <= 16 { +// unimplemented!("This should be done via transfer_thumb."); +// } else if size <= 20 { +// // Starting at size == 20, we have to switch to ARM due to lack of +// // accessible registers in THUMB mode. +// asm!( +// "ldmia {0}!, {{r2-r5,r8}}", +// "stmia {1}!, {{r2-r5,r8}}", +// inout(reg) src, inout(reg) dst, +// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, +// ) +// } else if size <= 24 { +// asm!( +// "push {{r9}}", +// "ldmia {0}!, {{r2-r5,r8-r9}}", +// "stmia {1}!, {{r2-r5,r8-r9}}", +// "pop {{r9}}", +// inout(reg) src, inout(reg) dst, +// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, +// ) +// } else if size <= 28 { +// asm!( +// "push {{r9}}", +// "ldmia {0}!, {{r2-r5,r8-r10}}", +// "stmia {1}!, {{r2-r5,r8-r10}}", +// "pop {{r9}}", +// inout(reg) src, inout(reg) dst, +// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, +// out("r10") _, +// ) +// } else if size <= 32 { +// asm!( +// "push {{r9}}", +// "ldmia {0}!, {{r2-r5,r8-r10,r12}}", +// "stmia {1}!, {{r2-r5,r8-r10,r12}}", +// "pop {{r9}}", +// inout(reg) src, inout(reg) dst, +// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, +// out("r10") _, out("r12") _, +// ) +// } else if size <= 36 { +// asm!( +// "push {{r9}}", +// "ldmia {0}!, {{r2-r5,r8-r10,r12,r14}}", +// "stmia {1}!, {{r2-r5,r8-r10,r12,r14}}", +// "pop {{r9}}", +// inout(reg) src, inout(reg) dst, +// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _, +// out("r10") _, out("r12") _, out("r14") _, +// ) +// } else { +// unimplemented!("Copy too large for use of ldmia/stmia."); +// } +// } /// The internal function for swapping the current value of a [`Static`] with /// another value.