diff --git a/examples/hello.rs b/examples/hello.rs index c847028..cadc763 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -35,7 +35,7 @@ extern "C" fn main() -> ! { { // get our tile data into memory. - //let src = ; + let src = CGA_8X8_THICK.as_ptr().cast::(); let dest = CHARBLOCK0_4BPP.index(0).as_usize() as *mut u32; let info = BitUnpackInfo { src_byte_len: size_of_val(&CGA_8X8_THICK) as u16, @@ -43,21 +43,26 @@ extern "C" fn main() -> ! { dest_elem_width: 4, offset_and_touch_zero: 0, }; - unsafe { BitUnPack(CGA_8X8_THICK.as_ptr().cast::(), dest, &info) }; + unsafe { BitUnPack(src, dest, &info) }; } - let tsb = text_screenblock(31); - for y in 0..16_u16 { - for x in 0..16_u16 { - let tsb_i = y * 32 + x; - let t_i = y * 16 + x; - tsb.index(tsb_i as usize).write(TextEntry::new().with_tile_id(t_i)); + { + // the the tilemap set up + let tsb = TileScreenblock::new(31); + for row in 0..16_usize { + for col in 0..16_usize { + let id = row * 16 + col; + let entry = TileEntry::new().with_tile_id(id as u16); + tsb.row_col(row, col).write(entry); + } } } - BG0CNT.write(BackgroundControl::new().with_screenblock(31)); - - DISPCNT.write(DisplayControl::new().with_show_bg0(true)); + { + // Set BG0 to use the tilemap we just made, and set it to be shown. + BG0CNT.write(BackgroundControl::new().with_screenblock(31)); + DISPCNT.write(DisplayControl::new().with_show_bg0(true)); + } let mut x_off = 0_u32; let mut y_off = 0_u32; diff --git a/src/mmio.rs b/src/mmio.rs index f1bf492..aa8411a 100644 --- a/src/mmio.rs +++ b/src/mmio.rs @@ -32,7 +32,7 @@ use crate::{ interrupts::IrqBits, video::{ BackgroundControl, Color, DisplayControl, DisplayStatus, WindowInside, - WindowOutside, Mosaic, BlendControl, Tile4, ObjAttr0, ObjAttr1, ObjAttr2, Tile8, TextEntry + WindowOutside, Mosaic, BlendControl, Tile4, ObjAttr0, ObjAttr1, ObjAttr2, Tile8, TileEntry }, dma::DmaControl, sound::{ @@ -222,56 +222,46 @@ def_mmio!(0x0600_4000 = CHARBLOCK1_8BPP: VolBlock; "Char def_mmio!(0x0600_8000 = CHARBLOCK2_8BPP: VolBlock; "Charblock 2, 8bpp view (256 tiles)."); def_mmio!(0x0600_C000 = CHARBLOCK3_8BPP: VolBlock; "Charblock 3, 8bpp view (256 tiles)."); -pub type TextScreenBlock = VolBlock; -pub type AffineScreenBlock0 = VolBlock; -pub type AffineScreenBlock1 = VolBlock; -pub type AffineScreenBlock2 = VolBlock; -pub type AffineScreenBlock3 = VolBlock; - -/// ## Panics -/// * Must be less than 32 #[inline] #[must_use] -pub const fn text_screenblock(index: usize) -> TextScreenBlock { - assert!(index < 32); - unsafe { VolBlock::new(0x0600_0000 + index * size_of::<[TextEntry;32*32]>()) } +const fn screenblock_addr(index: usize) -> usize { + /// The VRAM offset per screenblock. + const SCREENBLOCK_OFFSET: usize = 2_048; + + 0x0600_0000 + index * SCREENBLOCK_OFFSET } -/// ## Panics -/// * Must be less than 256 -#[inline] -#[must_use] -pub const fn affine_screenblock0(index: usize) -> AffineScreenBlock0 { - assert!(index < 256); - unsafe { VolBlock::new(0x0600_0000 + index * size_of::<[u8;16*16]>()) } +macro_rules! make_me_a_screenblock { + ($name:ident($t:ty), size: $size:literal, max_index: $max_index:literal) => { + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + #[repr(transparent)] + pub struct $name { + block: VolBlock<$t, Safe, Safe, {$size*$size}>, + } + impl $name { + #[inline] + #[must_use] + pub const fn new(index: usize) -> Self { + assert!(index < $max_index); + Self { block: unsafe { VolBlock::new(screenblock_addr(index)) } } + } + + #[inline] + #[must_use] + pub const fn row_col(self, row: usize, col: usize) -> VolAddress<$t, Safe, Safe> { + assert!(row < $size); + assert!(col < $size); + self.block.index(row * $size + col) + } + } + } } -/// ## Panics -/// * Must be less than 64 -#[inline] -#[must_use] -pub const fn affine_screenblock1(index: usize) -> AffineScreenBlock1 { - assert!(index < 64); - unsafe { VolBlock::new(0x0600_0000 + index * size_of::<[u8;32*32]>()) } -} - -/// ## Panics -/// * Must be less than 16 -#[inline] -#[must_use] -pub const fn affine_screenblock2(index: usize) -> AffineScreenBlock2 { - assert!(index < 16); - unsafe { VolBlock::new(0x0600_0000 + index * size_of::<[u8;64*64]>()) } -} - -/// ## Panics -/// * Must be less than 4 -#[inline] -#[must_use] -pub const fn affine_screenblock3(index: usize) -> AffineScreenBlock3 { - assert!(index < 4); - unsafe { VolBlock::new(0x0600_0000 + index * size_of::<[u8;128*128]>()) } -} +make_me_a_screenblock!(TileScreenblock(TileEntry), size: 32, max_index: 32); +make_me_a_screenblock!(AffineScreenBlock0(u8), size: 16, max_index: 32); +make_me_a_screenblock!(AffineScreenBlock1(u8), size: 32, max_index: 32); +make_me_a_screenblock!(AffineScreenBlock2(u8), size: 64, max_index: 30); +make_me_a_screenblock!(AffineScreenBlock3(u8), size: 128, max_index: 24); def_mmio!(0x0600_0000 = MODE3_BITMAP: VolBlock; "Mode 3 bitmap, 240x160.");