diff --git a/agb/src/agbabi/mod.rs b/agb/src/agbabi/mod.rs index 1f3df5a1..a53823cf 100644 --- a/agb/src/agbabi/mod.rs +++ b/agb/src/agbabi/mod.rs @@ -4,14 +4,6 @@ global_asm!(include_str!("macros.inc")); global_asm!(include_str!("memcpy.s")); global_asm!(include_str!("memset.s")); -extern "C" { - fn __aeabi_memcpy4(dest: *mut u32, src: *const u32, n: usize); -} - -pub(crate) unsafe fn memcpy(dest: *mut u32, src: *const u32, n: usize) { - __aeabi_memcpy4(dest, src, n); -} - #[cfg(test)] mod test { mod memset { diff --git a/agb/src/display/tiled/tile_copy.s b/agb/src/display/tiled/tile_copy.s new file mode 100644 index 00000000..866c0af8 --- /dev/null +++ b/agb/src/display/tiled/tile_copy.s @@ -0,0 +1,27 @@ +agb_arm_func copy_tile_8bpp + @ Arguments + @ r0 - pointer to the image data beginning + @ r1 - pointer to the target in vram + push {{r4-r8}} + +.rept 2 + ldmia r0!, {{r2-r8, r12}} + stmia r1!, {{r2-r8, r12}} +.endr + + pop {{r4-r8}} + bx lr +agb_arm_end copy_tile_8bpp + +agb_arm_func copy_tile_4bpp + @ Arguments + @ r0 - pointer to the image data beginning + @ r1 - pointer to the target in vram + push {{r4-r8}} + + ldmia r0!, {{r2-r8, r12}} + stmia r1!, {{r2-r8, r12}} + + pop {{r4-r8}} + bx lr +agb_arm_end copy_tile_4bpp \ No newline at end of file diff --git a/agb/src/display/tiled/vram_manager.rs b/agb/src/display/tiled/vram_manager.rs index 8ef68717..c2113983 100644 --- a/agb/src/display/tiled/vram_manager.rs +++ b/agb/src/display/tiled/vram_manager.rs @@ -4,7 +4,6 @@ use alloc::{slice, vec::Vec}; use crate::{ agb_alloc::{block_allocator::BlockAllocator, bump_allocator::StartEnd}, - agbabi, display::palette16, dma::dma_copy16, hash_map::{Entry, HashMap}, @@ -381,11 +380,13 @@ impl VRamManager { let tile_offset = (tile_id as usize) * tile_size; let tile_slice = &tile_set.tiles[tile_offset..(tile_offset + tile_size)]; - let tile_size = tile_slice.len(); let target_location = tile_reference.0.as_ptr() as *mut _; unsafe { - agbabi::memcpy(target_location, tile_slice.as_ptr() as *const _, tile_size); + match tile_set.format { + TileFormat::FourBpp => copy_tile_4bpp(tile_slice.as_ptr().cast(), target_location), + TileFormat::EightBpp => copy_tile_8bpp(tile_slice.as_ptr().cast(), target_location), + } } } @@ -409,3 +410,8 @@ impl VRamManager { } } } + +extern "C" { + fn copy_tile_4bpp(src: *const u32, dest: *mut u32); + fn copy_tile_8bpp(src: *const u32, dest: *mut u32); +} diff --git a/agb/src/global_asm.rs b/agb/src/global_asm.rs index b16f19b2..0af2e00e 100644 --- a/agb/src/global_asm.rs +++ b/agb/src/global_asm.rs @@ -6,3 +6,4 @@ global_asm!(include_str!("crt0.s")); global_asm!(include_str!("interrupt_handler.s")); global_asm!(include_str!("sound/mixer/mixer.s")); global_asm!(include_str!("save/asm_routines.s")); +global_asm!(include_str!("display/tiled/tile_copy.s"));