diff --git a/CHANGELOG.md b/CHANGELOG.md index 095a6e51..0378cbfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `find_colour_index_16` and `find_colour_index_256` to the `VRamManager` to find where a colour is in a palette. +### Changed + +- `dma.hblank_transfer` is no longer `unsafe`. + ## [0.20.2] - 2024/05/25 ### Fixed diff --git a/agb/examples/dma_effect_background_colour.rs b/agb/examples/dma_effect_background_colour.rs index f7386c59..7d1cfed1 100644 --- a/agb/examples/dma_effect_background_colour.rs +++ b/agb/examples/dma_effect_background_colour.rs @@ -37,12 +37,10 @@ fn main(mut gba: agb::Gba) -> ! { .expect("Should contain colour 0x732b"); loop { - let _background_color_transfer = unsafe { - dma.hblank_transfer( - &vram.background_palette_colour_dma(0, background_colour_index), - &colours, - ) - }; + let _background_color_transfer = dma.hblank_transfer( + &vram.background_palette_colour_dma(0, background_colour_index), + &colours, + ); vblank.wait_for_vblank(); } diff --git a/agb/examples/dma_effect_background_scroll.rs b/agb/examples/dma_effect_background_scroll.rs index eb5cdfaa..a74243ce 100644 --- a/agb/examples/dma_effect_background_scroll.rs +++ b/agb/examples/dma_effect_background_scroll.rs @@ -34,8 +34,7 @@ fn main(mut gba: agb::Gba) -> ! { let mut frame = 0; loop { - let _x_scroll_transfer = - unsafe { dma.hblank_transfer(&map.x_scroll_dma(), &offsets[frame..]) }; + let _x_scroll_transfer = dma.hblank_transfer(&map.x_scroll_dma(), &offsets[frame..]); vblank.wait_for_vblank(); frame += 1; diff --git a/agb/examples/dma_effect_circular_window.rs b/agb/examples/dma_effect_circular_window.rs index d98e6f60..cbdf8285 100644 --- a/agb/examples/dma_effect_circular_window.rs +++ b/agb/examples/dma_effect_circular_window.rs @@ -90,7 +90,7 @@ fn main(mut gba: agb::Gba) -> ! { window.commit(); let dma_controllable = window.win_in(WinIn::Win0).horizontal_position_dma(); - let _transfer = unsafe { dmas.dma0.hblank_transfer(&dma_controllable, &circle_poses) }; + let _transfer = dmas.dma0.hblank_transfer(&dma_controllable, &circle_poses); vblank.wait_for_vblank(); } diff --git a/agb/src/dma.rs b/agb/src/dma.rs index a16fc021..48e870db 100644 --- a/agb/src/dma.rs +++ b/agb/src/dma.rs @@ -70,18 +70,14 @@ impl Dma { /// drop the DmaTransferHandler return value until the next vblank interrupt to ensure that you /// a continuous effect. /// - /// # Safety - /// - /// While DmaTransferHandle is not dropped, the slice at `values` must not move in memory. - /// /// # Examples /// /// See the `dma_effect_*` examples in the repository to see some ways to use this. - pub unsafe fn hblank_transfer<'a, T>( - &'a self, + pub fn hblank_transfer( + &self, location: &DmaControllable, - values: &'a [T], - ) -> DmaTransferHandle<'a, T> + values: &[T], + ) -> DmaTransferHandle where T: Copy, { @@ -93,10 +89,13 @@ impl Dma { let n_transfers = (size_of::() / 2) as u32; - self.source_addr.set(handle.data.as_ptr().add(1) as u32); + self.source_addr.set(handle.data[1..].as_ptr() as u32); self.dest_addr.set(location.memory_location as u32); - location.memory_location.write_volatile(values[0]); + // SAFETY: by construction it is safe to write to location.memory_location + unsafe { + location.memory_location.write_volatile(values[0]); + } self.ctrl_addr.set( (0b10 << 0x15) | // keep destination address fixed @@ -127,17 +126,15 @@ impl DmaControllable { } } -pub struct DmaTransferHandle<'a, T> +pub struct DmaTransferHandle where T: Copy, { number: usize, data: Pin>, - - phantom: PhantomData<&'a ()>, } -impl<'a, T> DmaTransferHandle<'a, T> +impl DmaTransferHandle where T: Copy, { @@ -145,12 +142,11 @@ where Self { number, data: Box::into_pin(data.into()), - phantom: PhantomData, } } } -impl<'a, T> Drop for DmaTransferHandle<'a, T> +impl Drop for DmaTransferHandle where T: Copy, {