1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! Module for Background controls

use super::*;

/// BG0 Control. Read/Write. Display Mode 0/1 only.
pub const BG0CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_0008) };
/// BG1 Control. Read/Write. Display Mode 0/1 only.
pub const BG1CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_000A) };
/// BG2 Control. Read/Write. Display Mode 0/1/2 only.
pub const BG2CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_000C) };
/// BG3 Control. Read/Write.  Display Mode 0/2 only.
pub const BG3CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_000E) };

newtype! {
  /// Allows configuration of a background layer.
  ///
  /// Bits 0-1: BG Priority (lower number is higher priority, like an index)
  /// Bits 2-3: Character Base Block (0 through 3, 16k each)
  /// Bit 6: Mosaic mode
  /// Bit 7: is 8bpp
  /// Bit 8-12: Screen Base Block (0 through 31, 2k each)
  /// Bit 13: Display area overflow wraps (otherwise transparent, affine BG only)
  /// Bit 14-15: Screen Size
  BackgroundControlSetting, u16
}
impl BackgroundControlSetting {
  phantom_fields! {
    self.0: u16,
    bg_priority: 0-1,
    char_base_block: 2-3,
    mosaic: 6,
    is_8bpp: 7,
    screen_base_block: 8-12,
    affine_display_overflow_wrapping: 13,
    size: 14-15=BGSize<Zero, One, Two, Three>,
  }
}

/// The size of a background.
///
/// The meaning changes depending on if the background is Text or Affine mode.
///
/// * In text mode, the screen base block determines where to start reading the
///   tile arrangement data (2k). Size Zero gives one screen block of use. Size
///   One and Two cause two of them to be used (horizontally or vertically,
///   respectively). Size Three is four blocks used, [0,1] above and then [2,3]
///   below. Each screen base block used is always a 32x32 tile grid.
/// * In affine mode, the screen base block determines where to start reading
///   data followed by the size of data as shown. The number of tiles varies
///   according to the size used.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)]
pub enum BGSize {
  /// * Text: 256x256px (2k)
  /// * Affine: 128x128px (256b)
  Zero = 0,
  /// * Text: 512x256px (4k)
  /// * Affine: 256x256px (1k)
  One = 1,
  /// * Text: 256x512px (4k)
  /// * Affine: 512x512px (4k)
  Two = 2,
  /// * Text: 512x512px (8k)
  /// * Affine: 1024x1024px (16k)
  Three = 3,
}

/// BG0 X-Offset. Write only. Text mode only. 9 bits.
pub const BG0HOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0010) };
/// BG0 Y-Offset. Write only. Text mode only. 9 bits.
pub const BG0VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0012) };

/// BG1 X-Offset. Write only. Text mode only. 9 bits.
pub const BG1HOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0014) };
/// BG1 Y-Offset. Write only. Text mode only. 9 bits.
pub const BG1VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0016) };

/// BG2 X-Offset. Write only. Text mode only. 9 bits.
pub const BG2HOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0018) };
/// BG2 Y-Offset. Write only. Text mode only. 9 bits.
pub const BG2VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_001A) };

/// BG3 X-Offset. Write only. Text mode only. 9 bits.
pub const BG3HOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_001C) };
/// BG3 Y-Offset. Write only. Text mode only. 9 bits.
pub const BG3VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_001E) };

// TODO: affine backgrounds
// BG2X_L
// BG2X_H
// BG2Y_L
// BG2Y_H
// BG2PA
// BG2PB
// BG2PC
// BG2PD
// BG3PA
// BG3PB
// BG3PC
// BG3PD

// TODO: windowing
// pub const WIN0H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0040) };
// pub const WIN1H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0042) };
// pub const WIN0V: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0044) };
// pub const WIN1V: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0046) };
// pub const WININ: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0048) };
// pub const WINOUT: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_004A) };

// TODO: blending
// pub const BLDCNT: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0050) };
// pub const BLDALPHA: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0052) };
// pub const BLDY: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0054) };