mirror of
https://github.com/italicsjenga/gba.git
synced 2024-10-17 13:21:31 +11:00
Using asm and global_asm from core::arch module. (#157)
* Using asm and global_asm from core::arch module. * Commenting out some broken code with higher registers.
This commit is contained in:
parent
42e2836507
commit
093146fd8a
|
@ -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`:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::prelude::Color;
|
||||
|
||||
use core::arch::asm;
|
||||
use voladdress::*;
|
||||
|
||||
pub const WIDTH: usize = 240;
|
||||
|
|
|
@ -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"));
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
use crate::prelude::*;
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
mod locks;
|
||||
mod statics;
|
||||
|
||||
|
|
|
@ -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<T: Copy>(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<T: Copy>(mut dst: *mut T, mut src: *const T) {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
#[instruction_set(arm::a32)]
|
||||
#[allow(unused_assignments)]
|
||||
unsafe fn transfer_align4_arm<T: Copy>(mut dst: *mut T, mut src: *const T) {
|
||||
let size = size_of::<T>();
|
||||
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<T: Copy>(mut dst: *mut T, mut src: *const T) {
|
||||
// let size = size_of::<T>();
|
||||
// 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.
|
||||
|
|
Loading…
Reference in a new issue