Convert to using the recently split off voladdress lib

This commit is contained in:
Lokathor 2019-02-05 00:47:06 -07:00
parent dcd7e40b15
commit fc642c064d
15 changed files with 137 additions and 140 deletions

View file

@ -146,7 +146,7 @@ So, again using the `hello_magic` example, we had
And instead we could declare And instead we could declare
```rust ```rust
const MAGIC_LOCATION: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0000) }; const MAGIC_LOCATION: VolAddress<u16> = unsafe { VolAddress::new(0x400_0000) };
``` ```
### Using A VolAddress Value ### Using A VolAddress Value
@ -300,7 +300,7 @@ Now we can have something like:
```rust ```rust
const OTHER_MAGIC: VolAddressBlock<u16> = unsafe { const OTHER_MAGIC: VolAddressBlock<u16> = unsafe {
VolAddressBlock::new_unchecked( VolAddressBlock::new_unchecked(
VolAddress::new_unchecked(0x600_0000), VolAddress::new(0x600_0000),
240 * 160 240 * 160
) )
}; };

View file

@ -3,13 +3,13 @@
use super::*; use super::*;
/// BG0 Control. Read/Write. Display Mode 0/1 only. /// BG0 Control. Read/Write. Display Mode 0/1 only.
pub const BG0CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_0008) }; pub const BG0CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new(0x400_0008) };
/// BG1 Control. Read/Write. Display Mode 0/1 only. /// BG1 Control. Read/Write. Display Mode 0/1 only.
pub const BG1CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_000A) }; pub const BG1CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new(0x400_000A) };
/// BG2 Control. Read/Write. Display Mode 0/1/2 only. /// BG2 Control. Read/Write. Display Mode 0/1/2 only.
pub const BG2CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_000C) }; pub const BG2CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new(0x400_000C) };
/// BG3 Control. Read/Write. Display Mode 0/2 only. /// BG3 Control. Read/Write. Display Mode 0/2 only.
pub const BG3CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_000E) }; pub const BG3CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new(0x400_000E) };
newtype! { newtype! {
/// Allows configuration of a background layer. /// Allows configuration of a background layer.
@ -66,24 +66,24 @@ pub enum BGSize {
} }
/// BG0 X-Offset. Write only. Text mode only. 9 bits. /// BG0 X-Offset. Write only. Text mode only. 9 bits.
pub const BG0HOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0010) }; pub const BG0HOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_0010) };
/// BG0 Y-Offset. Write only. Text mode only. 9 bits. /// BG0 Y-Offset. Write only. Text mode only. 9 bits.
pub const BG0VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0012) }; pub const BG0VOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_0012) };
/// BG1 X-Offset. Write only. Text mode only. 9 bits. /// BG1 X-Offset. Write only. Text mode only. 9 bits.
pub const BG1HOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0014) }; pub const BG1HOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_0014) };
/// BG1 Y-Offset. Write only. Text mode only. 9 bits. /// BG1 Y-Offset. Write only. Text mode only. 9 bits.
pub const BG1VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0016) }; pub const BG1VOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_0016) };
/// BG2 X-Offset. Write only. Text mode only. 9 bits. /// BG2 X-Offset. Write only. Text mode only. 9 bits.
pub const BG2HOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0018) }; pub const BG2HOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_0018) };
/// BG2 Y-Offset. Write only. Text mode only. 9 bits. /// BG2 Y-Offset. Write only. Text mode only. 9 bits.
pub const BG2VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_001A) }; pub const BG2VOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_001A) };
/// BG3 X-Offset. Write only. Text mode only. 9 bits. /// BG3 X-Offset. Write only. Text mode only. 9 bits.
pub const BG3HOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_001C) }; pub const BG3HOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_001C) };
/// BG3 Y-Offset. Write only. Text mode only. 9 bits. /// BG3 Y-Offset. Write only. Text mode only. 9 bits.
pub const BG3VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_001E) }; pub const BG3VOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_001E) };
// TODO: affine backgrounds // TODO: affine backgrounds
// BG2X_L // BG2X_L
@ -100,14 +100,14 @@ pub const BG3VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00
// BG3PD // BG3PD
// TODO: windowing // TODO: windowing
// pub const WIN0H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0040) }; // pub const WIN0H: VolAddress<u16> = unsafe { VolAddress::new(0x400_0040) };
// pub const WIN1H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0042) }; // pub const WIN1H: VolAddress<u16> = unsafe { VolAddress::new(0x400_0042) };
// pub const WIN0V: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0044) }; // pub const WIN0V: VolAddress<u16> = unsafe { VolAddress::new(0x400_0044) };
// pub const WIN1V: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0046) }; // pub const WIN1V: VolAddress<u16> = unsafe { VolAddress::new(0x400_0046) };
// pub const WININ: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0048) }; // pub const WININ: VolAddress<u16> = unsafe { VolAddress::new(0x400_0048) };
// pub const WINOUT: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_004A) }; // pub const WINOUT: VolAddress<u16> = unsafe { VolAddress::new(0x400_004A) };
// TODO: blending // TODO: blending
// pub const BLDCNT: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0050) }; // pub const BLDCNT: VolAddress<u16> = unsafe { VolAddress::new(0x400_0050) };
// pub const BLDALPHA: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0052) }; // pub const BLDALPHA: VolAddress<u16> = unsafe { VolAddress::new(0x400_0052) };
// pub const BLDY: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0054) }; // pub const BLDY: VolAddress<u16> = unsafe { VolAddress::new(0x400_0054) };

View file

@ -3,7 +3,7 @@
use super::*; use super::*;
/// Color Special Effects Selection (R/W) /// Color Special Effects Selection (R/W)
pub const BLDCNT: VolAddress<ColorEffectSetting> = unsafe { VolAddress::new_unchecked(0x400_0050) }; pub const BLDCNT: VolAddress<ColorEffectSetting> = unsafe { VolAddress::new(0x400_0050) };
newtype! { newtype! {
ColorEffectSetting, u16 ColorEffectSetting, u16
@ -37,7 +37,7 @@ newtype_enum! {
} }
/// Alpha Blending Coefficients (R/W) (not W) /// Alpha Blending Coefficients (R/W) (not W)
pub const BLDALPHA: VolAddress<AlphaBlendingSetting> = unsafe { VolAddress::new_unchecked(0x400_0052) }; pub const BLDALPHA: VolAddress<AlphaBlendingSetting> = unsafe { VolAddress::new(0x400_0052) };
newtype! { newtype! {
AlphaBlendingSetting, u16 AlphaBlendingSetting, u16
@ -52,7 +52,7 @@ impl AlphaBlendingSetting {
} }
/// Brightness (Fade-In/Out) Coefficient (W) (not R/W) /// Brightness (Fade-In/Out) Coefficient (W) (not R/W)
pub const BLDY: VolAddress<BrightnessSetting> = unsafe { VolAddress::new_unchecked(0x400_0054) }; pub const BLDY: VolAddress<BrightnessSetting> = unsafe { VolAddress::new(0x400_0054) };
newtype! { newtype! {
BrightnessSetting, u32 BrightnessSetting, u32

View file

@ -5,7 +5,7 @@ use super::*;
/// LCD Control. Read/Write. /// LCD Control. Read/Write.
/// ///
/// The "force vblank" bit is always set when your Rust code first executes. /// The "force vblank" bit is always set when your Rust code first executes.
pub const DISPCNT: VolAddress<DisplayControlSetting> = unsafe { VolAddress::new_unchecked(0x400_0000) }; pub const DISPCNT: VolAddress<DisplayControlSetting> = unsafe { VolAddress::new(0x400_0000) };
newtype!( newtype!(
/// Setting for the display control register. /// Setting for the display control register.
@ -96,7 +96,7 @@ pub fn display_control() -> DisplayControlSetting {
} }
/// Display Status and IRQ Control. Read/Write. /// Display Status and IRQ Control. Read/Write.
pub const DISPSTAT: VolAddress<DisplayStatusSetting> = unsafe { VolAddress::new_unchecked(0x400_0004) }; pub const DISPSTAT: VolAddress<DisplayStatusSetting> = unsafe { VolAddress::new(0x400_0004) };
newtype!( newtype!(
/// A newtype over display status and interrupt control values. /// A newtype over display status and interrupt control values.
@ -122,7 +122,7 @@ impl DisplayStatusSetting {
/// Gives the current scanline that the display controller is working on. If /// Gives the current scanline that the display controller is working on. If
/// this is at or above the `VBLANK_SCANLINE` value then the display controller /// this is at or above the `VBLANK_SCANLINE` value then the display controller
/// is in a "vertical blank" period. /// is in a "vertical blank" period.
pub const VCOUNT: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0006) }; pub const VCOUNT: VolAddress<u16> = unsafe { VolAddress::new(0x400_0006) };
/// If the `VCOUNT` register reads equal to or above this then you're in vblank. /// If the `VCOUNT` register reads equal to or above this then you're in vblank.
pub const VBLANK_SCANLINE: u16 = 160; pub const VBLANK_SCANLINE: u16 = 160;
@ -145,7 +145,7 @@ pub fn spin_until_vdraw() {
} }
/// Global mosaic effect control. Write-only. /// Global mosaic effect control. Write-only.
pub const MOSAIC: VolAddress<MosaicSetting> = unsafe { VolAddress::new_unchecked(0x400_004C) }; pub const MOSAIC: VolAddress<MosaicSetting> = unsafe { VolAddress::new(0x400_004C) };
newtype! { newtype! {
/// Allows control of the Mosaic effect. /// Allows control of the Mosaic effect.

View file

@ -127,13 +127,13 @@ pub enum DMAStartTiming {
pub struct DMA0; pub struct DMA0;
impl DMA0 { impl DMA0 {
/// DMA 0 Source Address, read only. /// DMA 0 Source Address, read only.
const DMA0SAD: VolAddress<*const u32> = unsafe { VolAddress::new_unchecked(0x400_00B0) }; const DMA0SAD: VolAddress<*const u32> = unsafe { VolAddress::new(0x400_00B0) };
/// DMA 0 Destination Address, read only. /// DMA 0 Destination Address, read only.
const DMA0DAD: VolAddress<*mut u32> = unsafe { VolAddress::new_unchecked(0x400_00B4) }; const DMA0DAD: VolAddress<*mut u32> = unsafe { VolAddress::new(0x400_00B4) };
/// DMA 0 Word Count, read only. /// DMA 0 Word Count, read only.
const DMA0CNT_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00B8) }; const DMA0CNT_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_00B8) };
/// DMA 0 Control, read/write. /// DMA 0 Control, read/write.
const DMA0CNT_H: VolAddress<DMAControlSetting> = unsafe { VolAddress::new_unchecked(0x400_00BA) }; const DMA0CNT_H: VolAddress<DMAControlSetting> = unsafe { VolAddress::new(0x400_00BA) };
/// Assigns the source register. /// Assigns the source register.
/// ///
@ -188,13 +188,13 @@ impl DMA0 {
pub struct DMA1; pub struct DMA1;
impl DMA1 { impl DMA1 {
/// DMA 1 Source Address, read only. /// DMA 1 Source Address, read only.
const DMA1SAD: VolAddress<*const u32> = unsafe { VolAddress::new_unchecked(0x400_00BC) }; const DMA1SAD: VolAddress<*const u32> = unsafe { VolAddress::new(0x400_00BC) };
/// DMA 1 Destination Address, read only. /// DMA 1 Destination Address, read only.
const DMA1DAD: VolAddress<*mut u32> = unsafe { VolAddress::new_unchecked(0x400_00C0) }; const DMA1DAD: VolAddress<*mut u32> = unsafe { VolAddress::new(0x400_00C0) };
/// DMA 1 Word Count, read only. /// DMA 1 Word Count, read only.
const DMA1CNT_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00C4) }; const DMA1CNT_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_00C4) };
/// DMA 1 Control, read/write. /// DMA 1 Control, read/write.
const DMA1CNT_H: VolAddress<DMAControlSetting> = unsafe { VolAddress::new_unchecked(0x400_00C6) }; const DMA1CNT_H: VolAddress<DMAControlSetting> = unsafe { VolAddress::new(0x400_00C6) };
/// Assigns the source register. /// Assigns the source register.
/// ///
@ -249,13 +249,13 @@ impl DMA1 {
pub struct DMA2; pub struct DMA2;
impl DMA2 { impl DMA2 {
/// DMA 2 Source Address, read only. /// DMA 2 Source Address, read only.
const DMA2SAD: VolAddress<*const u32> = unsafe { VolAddress::new_unchecked(0x400_00C8) }; const DMA2SAD: VolAddress<*const u32> = unsafe { VolAddress::new(0x400_00C8) };
/// DMA 2 Destination Address, read only. /// DMA 2 Destination Address, read only.
const DMA2DAD: VolAddress<*mut u32> = unsafe { VolAddress::new_unchecked(0x400_00CC) }; const DMA2DAD: VolAddress<*mut u32> = unsafe { VolAddress::new(0x400_00CC) };
/// DMA 2 Word Count, read only. /// DMA 2 Word Count, read only.
const DMA2CNT_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00D0) }; const DMA2CNT_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_00D0) };
/// DMA 2 Control, read/write. /// DMA 2 Control, read/write.
const DMA2CNT_H: VolAddress<DMAControlSetting> = unsafe { VolAddress::new_unchecked(0x400_00D2) }; const DMA2CNT_H: VolAddress<DMAControlSetting> = unsafe { VolAddress::new(0x400_00D2) };
/// Assigns the source register. /// Assigns the source register.
/// ///
@ -311,13 +311,13 @@ impl DMA2 {
pub struct DMA3; pub struct DMA3;
impl DMA3 { impl DMA3 {
/// DMA 3 Source Address, read only. /// DMA 3 Source Address, read only.
const DMA3SAD: VolAddress<*const u32> = unsafe { VolAddress::new_unchecked(0x400_00D4) }; const DMA3SAD: VolAddress<*const u32> = unsafe { VolAddress::new(0x400_00D4) };
/// DMA 3 Destination Address, read only. /// DMA 3 Destination Address, read only.
const DMA3DAD: VolAddress<*mut u32> = unsafe { VolAddress::new_unchecked(0x400_00D8) }; const DMA3DAD: VolAddress<*mut u32> = unsafe { VolAddress::new(0x400_00D8) };
/// DMA 3 Word Count, read only. /// DMA 3 Word Count, read only.
const DMA3CNT_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00DC) }; const DMA3CNT_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_00DC) };
/// DMA 3 Control, read/write. /// DMA 3 Control, read/write.
const DMA3CNT_H: VolAddress<DMAControlSetting> = unsafe { VolAddress::new_unchecked(0x400_00DE) }; const DMA3CNT_H: VolAddress<DMAControlSetting> = unsafe { VolAddress::new(0x400_00DE) };
/// Assigns the source register. /// Assigns the source register.
/// ///

View file

@ -8,7 +8,7 @@ use super::*;
/// follow the "high-active" convention (hint: you probably do, it's far easier /// follow the "high-active" convention (hint: you probably do, it's far easier
/// to work with) then call `read_key_input()` rather than reading this register /// to work with) then call `read_key_input()` rather than reading this register
/// directly. It will perform the necessary bit flip operation for you. /// directly. It will perform the necessary bit flip operation for you.
pub const KEYINPUT: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0130) }; pub const KEYINPUT: VolAddress<u16> = unsafe { VolAddress::new(0x400_0130) };
/// A "tribool" value helps us interpret the arrow pad. /// A "tribool" value helps us interpret the arrow pad.
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -86,7 +86,7 @@ pub fn read_key_input() -> KeyInput {
/// Use this to configure when a keypad interrupt happens. /// Use this to configure when a keypad interrupt happens.
/// ///
/// See the `KeyInterruptSetting` type for more. /// See the `KeyInterruptSetting` type for more.
pub const KEYCNT: VolAddress<KeyInterruptSetting> = unsafe { VolAddress::new_unchecked(0x400_0132) }; pub const KEYCNT: VolAddress<KeyInterruptSetting> = unsafe { VolAddress::new(0x400_0132) };
newtype! { newtype! {
/// Allows configuration of when a keypad interrupt fires. /// Allows configuration of when a keypad interrupt fires.

View file

@ -4,7 +4,7 @@ use super::*;
//TODO within these "read/write" registers only some bits are actually read/write! //TODO within these "read/write" registers only some bits are actually read/write!
/// Sound Channel 1 Sweep Register (`NR10`). Read/Write. /// Sound Channel 1 Sweep Register (`NR10`). Read/Write.
pub const SOUND1CNT_L: VolAddress<SweepRegisterSetting> = unsafe { VolAddress::new_unchecked(0x400_0060) }; pub const SOUND1CNT_L: VolAddress<SweepRegisterSetting> = unsafe { VolAddress::new(0x400_0060) };
newtype! { newtype! {
SweepRegisterSetting, u16 SweepRegisterSetting, u16
@ -20,7 +20,7 @@ impl SweepRegisterSetting {
} }
/// Sound Channel 1 Duty/Length/Envelope (`NR11`, `NR12`). Read/Write. /// Sound Channel 1 Duty/Length/Envelope (`NR11`, `NR12`). Read/Write.
pub const SOUND1CNT_H: VolAddress<DutyLenEnvelopeSetting> = unsafe { VolAddress::new_unchecked(0x400_0062) }; pub const SOUND1CNT_H: VolAddress<DutyLenEnvelopeSetting> = unsafe { VolAddress::new(0x400_0062) };
newtype! { newtype! {
DutyLenEnvelopeSetting, u16 DutyLenEnvelopeSetting, u16
@ -38,7 +38,7 @@ impl DutyLenEnvelopeSetting {
} }
/// Sound Channel 1 Frequency/Control (`NR13`, `NR14`). Read/Write. /// Sound Channel 1 Frequency/Control (`NR13`, `NR14`). Read/Write.
pub const SOUND1CNT_X: VolAddress<FrequencyControlSetting> = unsafe { VolAddress::new_unchecked(0x400_0064) }; pub const SOUND1CNT_X: VolAddress<FrequencyControlSetting> = unsafe { VolAddress::new(0x400_0064) };
newtype! { newtype! {
FrequencyControlSetting, u32 // TODO: u16 or u32? FrequencyControlSetting, u32 // TODO: u16 or u32?
@ -54,13 +54,13 @@ impl FrequencyControlSetting {
} }
/// Sound Channel 2 Channel 2 Duty/Length/Envelope (`NR21`, `NR22`). Read/Write. /// Sound Channel 2 Channel 2 Duty/Length/Envelope (`NR21`, `NR22`). Read/Write.
pub const SOUND2CNT_L: VolAddress<DutyLenEnvelopeSetting> = unsafe { VolAddress::new_unchecked(0x400_0068) }; pub const SOUND2CNT_L: VolAddress<DutyLenEnvelopeSetting> = unsafe { VolAddress::new(0x400_0068) };
/// Sound Channel 2 Frequency/Control (`NR23`, `NR24`). Read/Write. /// Sound Channel 2 Frequency/Control (`NR23`, `NR24`). Read/Write.
pub const SOUND2CNT_H: VolAddress<FrequencyControlSetting> = unsafe { VolAddress::new_unchecked(0x400_006C) }; pub const SOUND2CNT_H: VolAddress<FrequencyControlSetting> = unsafe { VolAddress::new(0x400_006C) };
/// Sound Channel 3 Stop/Wave RAM select (`NR23`, `NR24`). Read/Write. /// Sound Channel 3 Stop/Wave RAM select (`NR23`, `NR24`). Read/Write.
pub const SOUND3CNT_L: VolAddress<StopWaveRAMSelectSetting> = unsafe { VolAddress::new_unchecked(0x400_0070) }; pub const SOUND3CNT_L: VolAddress<StopWaveRAMSelectSetting> = unsafe { VolAddress::new(0x400_0070) };
newtype! { newtype! {
StopWaveRAMSelectSetting, u16 StopWaveRAMSelectSetting, u16
@ -76,7 +76,7 @@ impl StopWaveRAMSelectSetting {
} }
/// Sound Channel 3 Length/Volume (`NR23`, `NR24`). Read/Write. /// Sound Channel 3 Length/Volume (`NR23`, `NR24`). Read/Write.
pub const SOUND3CNT_H: VolAddress<LengthVolumeSetting> = unsafe { VolAddress::new_unchecked(0x400_0072) }; pub const SOUND3CNT_H: VolAddress<LengthVolumeSetting> = unsafe { VolAddress::new(0x400_0072) };
newtype! { newtype! {
LengthVolumeSetting, u16 LengthVolumeSetting, u16
@ -92,27 +92,27 @@ impl LengthVolumeSetting {
} }
/// Sound Channel 3 Frequency/Control (`NR33`, `NR34`). Read/Write. /// Sound Channel 3 Frequency/Control (`NR33`, `NR34`). Read/Write.
pub const SOUND3CNT_X: VolAddress<FrequencyControlSetting> = unsafe { VolAddress::new_unchecked(0x400_0074) }; pub const SOUND3CNT_X: VolAddress<FrequencyControlSetting> = unsafe { VolAddress::new(0x400_0074) };
/// Channel 3 Wave Pattern RAM (W/R) /// Channel 3 Wave Pattern RAM (W/R)
pub const WAVE_RAM0_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0090) }; pub const WAVE_RAM0_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_0090) };
/// Channel 3 Wave Pattern RAM (W/R) /// Channel 3 Wave Pattern RAM (W/R)
pub const WAVE_RAM0_H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0092) }; pub const WAVE_RAM0_H: VolAddress<u16> = unsafe { VolAddress::new(0x400_0092) };
/// Channel 3 Wave Pattern RAM (W/R) /// Channel 3 Wave Pattern RAM (W/R)
pub const WAVE_RAM1_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0094) }; pub const WAVE_RAM1_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_0094) };
/// Channel 3 Wave Pattern RAM (W/R) /// Channel 3 Wave Pattern RAM (W/R)
pub const WAVE_RAM1_H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0096) }; pub const WAVE_RAM1_H: VolAddress<u16> = unsafe { VolAddress::new(0x400_0096) };
/// Channel 3 Wave Pattern RAM (W/R) /// Channel 3 Wave Pattern RAM (W/R)
pub const WAVE_RAM2_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0098) }; pub const WAVE_RAM2_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_0098) };
/// Channel 3 Wave Pattern RAM (W/R) /// Channel 3 Wave Pattern RAM (W/R)
pub const WAVE_RAM2_H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_009A) }; pub const WAVE_RAM2_H: VolAddress<u16> = unsafe { VolAddress::new(0x400_009A) };
/// Channel 3 Wave Pattern RAM (W/R) /// Channel 3 Wave Pattern RAM (W/R)
pub const WAVE_RAM3_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_009C) }; pub const WAVE_RAM3_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_009C) };
/// Channel 3 Wave Pattern RAM (W/R) /// Channel 3 Wave Pattern RAM (W/R)
pub const WAVE_RAM3_H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_009E) }; pub const WAVE_RAM3_H: VolAddress<u16> = unsafe { VolAddress::new(0x400_009E) };
/// Sound Channel 4 Length/Envelope (`NR41`, `NR42`). Read/Write. /// Sound Channel 4 Length/Envelope (`NR41`, `NR42`). Read/Write.
pub const SOUND4CNT_L: VolAddress<LengthEnvelopeSetting> = unsafe { VolAddress::new_unchecked(0x400_0078) }; pub const SOUND4CNT_L: VolAddress<LengthEnvelopeSetting> = unsafe { VolAddress::new(0x400_0078) };
newtype! { newtype! {
LengthEnvelopeSetting, u32 // TODO: is this u32? LengthEnvelopeSetting, u32 // TODO: is this u32?
@ -129,7 +129,7 @@ impl LengthEnvelopeSetting {
} }
/// Sound Channel 4 Frequency/Control (`NR43`, `NR44`). Read/Write. /// Sound Channel 4 Frequency/Control (`NR43`, `NR44`). Read/Write.
pub const SOUND4CNT_H: VolAddress<NoiseFrequencySetting> = unsafe { VolAddress::new_unchecked(0x400_007C) }; pub const SOUND4CNT_H: VolAddress<NoiseFrequencySetting> = unsafe { VolAddress::new(0x400_007C) };
newtype! { newtype! {
NoiseFrequencySetting, u32 // TODO: is this u32? NoiseFrequencySetting, u32 // TODO: is this u32?
@ -149,16 +149,16 @@ impl NoiseFrequencySetting {
// TODO: unify FIFO as // TODO: unify FIFO as
/// Sound A FIFO, Data 0 and Data 1 (W) /// Sound A FIFO, Data 0 and Data 1 (W)
pub const FIFO_A_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00A0) }; pub const FIFO_A_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_00A0) };
/// Sound A FIFO, Data 2 and Data 3 (W) /// Sound A FIFO, Data 2 and Data 3 (W)
pub const FIFO_A_H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00A2) }; pub const FIFO_A_H: VolAddress<u16> = unsafe { VolAddress::new(0x400_00A2) };
/// Sound B FIFO, Data 0 and Data 1 (W) /// Sound B FIFO, Data 0 and Data 1 (W)
pub const FIFO_B_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00A4) }; pub const FIFO_B_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_00A4) };
/// Sound B FIFO, Data 2 and Data 3 (W) /// Sound B FIFO, Data 2 and Data 3 (W)
pub const FIFO_B_H: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00A6) }; pub const FIFO_B_H: VolAddress<u16> = unsafe { VolAddress::new(0x400_00A6) };
/// Channel L/R Volume/Enable (`NR50`, `NR51`). Read/Write. /// Channel L/R Volume/Enable (`NR50`, `NR51`). Read/Write.
pub const SOUNDCNT_L: VolAddress<NonWaveVolumeEnableSetting> = unsafe { VolAddress::new_unchecked(0x400_0080) }; pub const SOUNDCNT_L: VolAddress<NonWaveVolumeEnableSetting> = unsafe { VolAddress::new(0x400_0080) };
newtype! { newtype! {
NonWaveVolumeEnableSetting, u16 NonWaveVolumeEnableSetting, u16
@ -175,7 +175,7 @@ impl NonWaveVolumeEnableSetting {
} }
/// DMA Sound Control/Mixing. Read/Write. /// DMA Sound Control/Mixing. Read/Write.
pub const SOUNDCNT_H: VolAddress<WaveVolumeEnableSetting> = unsafe { VolAddress::new_unchecked(0x400_0082) }; pub const SOUNDCNT_H: VolAddress<WaveVolumeEnableSetting> = unsafe { VolAddress::new(0x400_0082) };
newtype! { newtype! {
WaveVolumeEnableSetting, u16 WaveVolumeEnableSetting, u16
@ -206,7 +206,7 @@ newtype_enum! {
} }
/// Sound on/off (`NR52`). Read/Write. /// Sound on/off (`NR52`). Read/Write.
pub const SOUNDCNT_X: VolAddress<SoundMasterSetting> = unsafe { VolAddress::new_unchecked(0x400_0084) }; pub const SOUNDCNT_X: VolAddress<SoundMasterSetting> = unsafe { VolAddress::new(0x400_0084) };
newtype! { newtype! {
SoundMasterSetting, u16 SoundMasterSetting, u16
@ -224,7 +224,7 @@ impl SoundMasterSetting {
} }
/// Sound on/off (`NR52`). Read/Write. /// Sound on/off (`NR52`). Read/Write.
pub const SOUNDBIAS: VolAddress<SoundPWMSetting> = unsafe { VolAddress::new_unchecked(0x400_0088) }; pub const SOUNDBIAS: VolAddress<SoundPWMSetting> = unsafe { VolAddress::new(0x400_0088) };
newtype! { newtype! {
SoundPWMSetting, u16 SoundPWMSetting, u16

View file

@ -28,28 +28,28 @@ use super::*;
// TODO: striding blocks? // TODO: striding blocks?
/// Timer 0 Counter/Reload. Special (see module). /// Timer 0 Counter/Reload. Special (see module).
pub const TM0CNT_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0100) }; pub const TM0CNT_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_0100) };
/// Timer 1 Counter/Reload. Special (see module). /// Timer 1 Counter/Reload. Special (see module).
pub const TM1CNT_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0104) }; pub const TM1CNT_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_0104) };
/// Timer 2 Counter/Reload. Special (see module). /// Timer 2 Counter/Reload. Special (see module).
pub const TM2CNT_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_0108) }; pub const TM2CNT_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_0108) };
/// Timer 3 Counter/Reload. Special (see module). /// Timer 3 Counter/Reload. Special (see module).
pub const TM3CNT_L: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_010C) }; pub const TM3CNT_L: VolAddress<u16> = unsafe { VolAddress::new(0x400_010C) };
/// Timer 0 Control. Read/Write. /// Timer 0 Control. Read/Write.
pub const TM0CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new_unchecked(0x400_0102) }; pub const TM0CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new(0x400_0102) };
/// Timer 1 Control. Read/Write. /// Timer 1 Control. Read/Write.
pub const TM1CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new_unchecked(0x400_0106) }; pub const TM1CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new(0x400_0106) };
/// Timer 2 Control. Read/Write. /// Timer 2 Control. Read/Write.
pub const TM2CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new_unchecked(0x400_010A) }; pub const TM2CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new(0x400_010A) };
/// Timer 3 Control. Read/Write. /// Timer 3 Control. Read/Write.
pub const TM3CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new_unchecked(0x400_010E) }; pub const TM3CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new(0x400_010E) };
newtype! { newtype! {
/// Allows control of a timer unit. /// Allows control of a timer unit.

View file

@ -3,10 +3,10 @@
use super::*; use super::*;
/// Window 0 Horizontal Dimensions (W) /// Window 0 Horizontal Dimensions (W)
pub const WIN0H: VolAddress<HorizontalWindowSetting> = unsafe { VolAddress::new_unchecked(0x400_0040) }; pub const WIN0H: VolAddress<HorizontalWindowSetting> = unsafe { VolAddress::new(0x400_0040) };
/// Window 1 Horizontal Dimensions (W) /// Window 1 Horizontal Dimensions (W)
pub const WIN1H: VolAddress<HorizontalWindowSetting> = unsafe { VolAddress::new_unchecked(0x400_0042) }; pub const WIN1H: VolAddress<HorizontalWindowSetting> = unsafe { VolAddress::new(0x400_0042) };
newtype! { newtype! {
HorizontalWindowSetting, u16 HorizontalWindowSetting, u16
@ -21,10 +21,10 @@ impl HorizontalWindowSetting {
} }
/// Window 0 Vertical Dimensions (W) /// Window 0 Vertical Dimensions (W)
pub const WIN0V: VolAddress<VerticalWindowSetting> = unsafe { VolAddress::new_unchecked(0x400_0044) }; pub const WIN0V: VolAddress<VerticalWindowSetting> = unsafe { VolAddress::new(0x400_0044) };
/// Window 1 Vertical Dimensions (W) /// Window 1 Vertical Dimensions (W)
pub const WIN1V: VolAddress<VerticalWindowSetting> = unsafe { VolAddress::new_unchecked(0x400_0046) }; pub const WIN1V: VolAddress<VerticalWindowSetting> = unsafe { VolAddress::new(0x400_0046) };
newtype! { newtype! {
VerticalWindowSetting, u16 VerticalWindowSetting, u16
@ -39,7 +39,7 @@ impl VerticalWindowSetting {
} }
/// Control of Inside of Window(s) (R/W) /// Control of Inside of Window(s) (R/W)
pub const WININ: VolAddress<InsideWindowSetting> = unsafe { VolAddress::new_unchecked(0x400_0048) }; pub const WININ: VolAddress<InsideWindowSetting> = unsafe { VolAddress::new(0x400_0048) };
newtype! { newtype! {
InsideWindowSetting, u16 InsideWindowSetting, u16
@ -64,7 +64,7 @@ impl InsideWindowSetting {
} }
/// Control of Outside of Windows & Inside of OBJ Window (R/W) /// Control of Outside of Windows & Inside of OBJ Window (R/W)
pub const WINOUT: VolAddress<OutsideWindowSetting> = unsafe { VolAddress::new_unchecked(0x400_004A) }; pub const WINOUT: VolAddress<OutsideWindowSetting> = unsafe { VolAddress::new(0x400_004A) };
newtype! { newtype! {
OutsideWindowSetting, u16 OutsideWindowSetting, u16

View file

@ -19,6 +19,7 @@
//! do, it's a giant bag of Undefined Behavior. //! do, it's a giant bag of Undefined Behavior.
pub(crate) use gba_proc_macro::phantom_fields; pub(crate) use gba_proc_macro::phantom_fields;
pub(crate) use voladdress::{VolAddress, VolBlock};
/// Assists in defining a newtype wrapper over some base type. /// Assists in defining a newtype wrapper over some base type.
/// ///
@ -105,7 +106,6 @@ macro_rules! newtype_enum {
} }
pub mod base; pub mod base;
pub(crate) use self::base::*;
pub mod bios; pub mod bios;

View file

@ -24,13 +24,13 @@ pub struct MGBADebug {
bytes_written: u8, bytes_written: u8,
} }
impl MGBADebug { impl MGBADebug {
const ENABLE_ADDRESS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x4fff780) }; const ENABLE_ADDRESS: VolAddress<u16> = unsafe { VolAddress::new(0x4fff780) };
const ENABLE_ADDRESS_INPUT: u16 = 0xC0DE; const ENABLE_ADDRESS_INPUT: u16 = 0xC0DE;
const ENABLE_ADDRESS_OUTPUT: u16 = 0x1DEA; const ENABLE_ADDRESS_OUTPUT: u16 = 0x1DEA;
const OUTPUT_BASE: VolAddress<u8> = unsafe { VolAddress::new_unchecked(0x4fff600) }; const OUTPUT_BASE: VolAddress<u8> = unsafe { VolAddress::new(0x4fff600) };
const SEND_ADDRESS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x4fff700) }; const SEND_ADDRESS: VolAddress<u16> = unsafe { VolAddress::new(0x4fff700) };
const SEND_FLAG: u16 = 0x100; const SEND_FLAG: u16 = 0x100;
/// Gives a new MGBADebug, if running within `mGBA` /// Gives a new MGBADebug, if running within `mGBA`

View file

@ -2,6 +2,8 @@
use super::*; use super::*;
use typenum::consts::{U128, U32};
newtype! { newtype! {
/// 0th part of an object's attributes. /// 0th part of an object's attributes.
/// ///
@ -137,7 +139,8 @@ pub struct ObjectAttributes {
/// The object attributes, but there are gaps in the array, so we must not /// The object attributes, but there are gaps in the array, so we must not
/// expose this directly. /// expose this directly.
const OBJ_ATTR_APPROX: VolAddressBlock<[u16; 4]> = unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(0x700_0000), 128) }; const OBJ_ATTR_APPROX: VolBlock<[u16; 4], U128> = unsafe { VolBlock::new(0x700_0000) };
// TODO: VolSeries
pub fn write_obj_attributes(slot: usize, attributes: ObjectAttributes) -> Option<()> { pub fn write_obj_attributes(slot: usize, attributes: ObjectAttributes) -> Option<()> {
OBJ_ATTR_APPROX.get(slot).map(|va| unsafe { OBJ_ATTR_APPROX.get(slot).map(|va| unsafe {
@ -169,7 +172,8 @@ pub struct AffineParameters {
/// The object attributes, but there are gaps in the array, so we must not /// The object attributes, but there are gaps in the array, so we must not
/// expose this directly. /// expose this directly.
const AFFINE_PARAMS_APPROX: VolAddressBlock<[i16; 16]> = unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(0x700_0000), 32) }; const AFFINE_PARAMS_APPROX: VolBlock<[i16; 16], U32> = unsafe { VolBlock::new(0x700_0000) };
// TODO: VolSeries
pub fn write_affine_parameters(slot: usize, params: AffineParameters) -> Option<()> { pub fn write_affine_parameters(slot: usize, params: AffineParameters) -> Option<()> {
AFFINE_PARAMS_APPROX.get(slot).map(|va| unsafe { AFFINE_PARAMS_APPROX.get(slot).map(|va| unsafe {

View file

@ -23,18 +23,17 @@
//! display will show if no background or object draws over top of a given pixel //! display will show if no background or object draws over top of a given pixel
//! during rendering. //! during rendering.
use super::{ use super::*;
base::volatile::{VolAddress, VolAddressBlock},
Color, use typenum::consts::U256;
};
// TODO: PalIndex newtypes? // TODO: PalIndex newtypes?
/// The `PALRAM` for background colors, 256 slot view. /// The `PALRAM` for background colors, 256 slot view.
pub const PALRAM_BG: VolAddressBlock<Color> = unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(0x500_0000), 256) }; pub const PALRAM_BG: VolBlock<Color, U256> = unsafe { VolBlock::new(0x500_0000) };
/// The `PALRAM` for object colors, 256 slot view. /// The `PALRAM` for object colors, 256 slot view.
pub const PALRAM_OBJ: VolAddressBlock<Color> = unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(0x500_0200), 256) }; pub const PALRAM_OBJ: VolBlock<Color, U256> = unsafe { VolBlock::new(0x500_0200) };
/// Obtains the address of the specified 8bpp background palette slot. /// Obtains the address of the specified 8bpp background palette slot.
pub const fn index_palram_bg_8bpp(slot: u8) -> VolAddress<Color> { pub const fn index_palram_bg_8bpp(slot: u8) -> VolAddress<Color> {

View file

@ -15,6 +15,8 @@
pub(crate) use super::*; pub(crate) use super::*;
use typenum::consts::{U256, U32, U512, U6};
pub mod affine; pub mod affine;
pub mod bitmap; pub mod bitmap;
pub mod text; pub mod text;
@ -28,11 +30,10 @@ pub mod text;
pub const VRAM_BASE_USIZE: usize = 0x600_0000; pub const VRAM_BASE_USIZE: usize = 0x600_0000;
/// The character base blocks. /// The character base blocks.
pub const CHAR_BASE_BLOCKS: VolAddressBlock<[u8; 0x4000]> = unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(VRAM_BASE_USIZE), 6) }; pub const CHAR_BASE_BLOCKS: VolBlock<[u8; 0x4000], U6> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
/// The screen entry base blocks. /// The screen entry base blocks.
pub const SCREEN_BASE_BLOCKS: VolAddressBlock<[u8; 0x800]> = pub const SCREEN_BASE_BLOCKS: VolBlock<[u8; 0x800], U32> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(VRAM_BASE_USIZE), 32) };
newtype! { newtype! {
/// An 8x8 tile with 4bpp, packed as `u32` values for proper alignment. /// An 8x8 tile with 4bpp, packed as `u32` values for proper alignment.
@ -47,11 +48,11 @@ newtype! {
} }
/// Gives the specified charblock in 4bpp view. /// Gives the specified charblock in 4bpp view.
pub fn get_4bpp_character_block(slot: usize) -> VolAddressBlock<Tile4bpp> { pub fn get_4bpp_character_block(slot: usize) -> VolBlock<Tile4bpp, U512> {
unsafe { VolAddressBlock::new_unchecked(CHAR_BASE_BLOCKS.index(slot).cast::<Tile4bpp>(), 512) } unsafe { VolBlock::new(CHAR_BASE_BLOCKS.index(slot).to_usize()) }
} }
/// Gives the specified charblock in 8bpp view. /// Gives the specified charblock in 8bpp view.
pub fn get_8bpp_character_block(slot: usize) -> VolAddressBlock<Tile8bpp> { pub fn get_8bpp_character_block(slot: usize) -> VolBlock<Tile8bpp, U256> {
unsafe { VolAddressBlock::new_unchecked(CHAR_BASE_BLOCKS.index(slot).cast::<Tile8bpp>(), 256) } unsafe { VolBlock::new(CHAR_BASE_BLOCKS.index(slot).to_usize()) }
} }

View file

@ -2,6 +2,9 @@
use super::*; use super::*;
use core::ops::{Div, Mul};
use typenum::consts::{U128, U160, U2, U256, U4};
/// Mode 3 is a bitmap mode with full color and full resolution. /// Mode 3 is a bitmap mode with full color and full resolution.
/// ///
/// * **Width:** 240 /// * **Width:** 240
@ -27,12 +30,10 @@ impl Mode3 {
/// ///
/// Use `col + row * SCREEN_WIDTH` to get the address of an individual pixel, /// Use `col + row * SCREEN_WIDTH` to get the address of an individual pixel,
/// or use the helpers provided in this module. /// or use the helpers provided in this module.
pub const VRAM: VolAddressBlock<Color> = pub const VRAM: VolBlock<Color, <U256 as Mul<U160>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(VRAM_BASE_USIZE), Self::SCREEN_PIXEL_COUNT) };
/// private iterator over the pixels, two at a time /// private iterator over the pixels, two at a time
const BULK_ITER: VolAddressIter<u32> = const VRAM_BULK: VolBlock<u32, <<U256 as Mul<U160>>::Output as Div<U2>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(VRAM_BASE_USIZE), Self::SCREEN_PIXEL_COUNT / 2).iter() };
/// Reads the pixel at the given (col,row). /// Reads the pixel at the given (col,row).
/// ///
@ -56,7 +57,7 @@ impl Mode3 {
pub fn clear_to(color: Color) { pub fn clear_to(color: Color) {
let color32 = color.0 as u32; let color32 = color.0 as u32;
let bulk_color = color32 << 16 | color32; let bulk_color = color32 << 16 | color32;
for va in Self::BULK_ITER { for va in Self::VRAM_BULK.iter() {
va.write(bulk_color) va.write(bulk_color)
} }
} }
@ -101,22 +102,22 @@ impl Mode4 {
const SCREEN_U32_COUNT: usize = Self::SCREEN_PIXEL_COUNT / 4; const SCREEN_U32_COUNT: usize = Self::SCREEN_PIXEL_COUNT / 4;
// TODO: newtype this? // TODO: newtype this?
const PAGE0_BASE: VolAddress<u8> = unsafe { VolAddress::new_unchecked(VRAM_BASE_USIZE) }; const PAGE0_BLOCK8: VolBlock<u8, <U256 as Mul<U160>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
// TODO: newtype this? // TODO: newtype this?
const PAGE0_BLOCK: VolAddressBlock<u8> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE0_BASE, Self::SCREEN_PIXEL_COUNT) }; const PAGE1_BLOCK8: VolBlock<u8, <U256 as Mul<U160>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE + 0xA000) };
// TODO: newtype this? // TODO: newtype this?
const PAGE1_BASE: VolAddress<u8> = unsafe { VolAddress::new_unchecked(VRAM_BASE_USIZE + 0xA000) }; const PAGE0_BLOCK16: VolBlock<u16, <<U256 as Mul<U160>>::Output as Div<U2>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
// TODO: newtype this? // TODO: newtype this?
const PAGE1_BLOCK: VolAddressBlock<u8> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE1_BASE, Self::SCREEN_PIXEL_COUNT) }; const PAGE1_BLOCK16: VolBlock<u16, <<U256 as Mul<U160>>::Output as Div<U2>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE + 0xA000) };
/// private iterator over the page0 pixels, four at a time /// private iterator over the page0 pixels, four at a time
const BULK_ITER0: VolAddressIter<u32> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE0_BASE.cast::<u32>(), Self::SCREEN_U32_COUNT).iter() }; const PAGE0_BULK32: VolBlock<u32, <<U256 as Mul<U160>>::Output as Div<U4>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
/// private iterator over the page1 pixels, four at a time /// private iterator over the page1 pixels, four at a time
const BULK_ITER1: VolAddressIter<u32> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE1_BASE.cast::<u32>(), Self::SCREEN_U32_COUNT).iter() }; const PAGE1_BULK32: VolBlock<u32, <<U256 as Mul<U160>>::Output as Div<U4>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE + 0xA000) };
/// Reads the pixel at the given (col,row). /// Reads the pixel at the given (col,row).
/// ///
@ -126,9 +127,9 @@ impl Mode4 {
pub fn read_pixel(page1: bool, col: usize, row: usize) -> Option<u8> { pub fn read_pixel(page1: bool, col: usize, row: usize) -> Option<u8> {
// Note(Lokathor): byte _reads_ from VRAM are okay. // Note(Lokathor): byte _reads_ from VRAM are okay.
if page1 { if page1 {
Self::PAGE1_BLOCK.get(col + row * Self::SCREEN_WIDTH).map(VolAddress::read) Self::PAGE1_BLOCK8.get(col + row * Self::SCREEN_WIDTH).map(VolAddress::read)
} else { } else {
Self::PAGE0_BLOCK.get(col + row * Self::SCREEN_WIDTH).map(VolAddress::read) Self::PAGE0_BLOCK8.get(col + row * Self::SCREEN_WIDTH).map(VolAddress::read)
} }
} }
@ -145,9 +146,9 @@ impl Mode4 {
let rounded_down_index = real_index & !1; let rounded_down_index = real_index & !1;
let address: VolAddress<u16> = unsafe { let address: VolAddress<u16> = unsafe {
if page1 { if page1 {
Self::PAGE1_BASE.offset(rounded_down_index as isize).cast() Self::PAGE1_BLOCK8.index(rounded_down_index).cast()
} else { } else {
Self::PAGE0_BASE.offset(rounded_down_index as isize).cast() Self::PAGE0_BLOCK8.index(rounded_down_index).cast()
} }
}; };
if real_index == rounded_down_index { if real_index == rounded_down_index {
@ -173,12 +174,10 @@ impl Mode4 {
pub fn write_wide_pixel(page1: bool, wide_col: usize, row: usize, wide_pal8bpp: u16) -> Option<()> { pub fn write_wide_pixel(page1: bool, wide_col: usize, row: usize, wide_pal8bpp: u16) -> Option<()> {
if wide_col < Self::SCREEN_WIDTH / 2 && row < Self::SCREEN_HEIGHT { if wide_col < Self::SCREEN_WIDTH / 2 && row < Self::SCREEN_HEIGHT {
let wide_index = wide_col + row * Self::SCREEN_WIDTH / 2; let wide_index = wide_col + row * Self::SCREEN_WIDTH / 2;
let address: VolAddress<u16> = unsafe { let address: VolAddress<u16> = if page1 {
if page1 { Self::PAGE1_BLOCK16.index(wide_index)
Self::PAGE1_BASE.cast::<u16>().offset(wide_index as isize) } else {
} else { Self::PAGE0_BLOCK16.index(wide_index)
Self::PAGE0_BASE.cast::<u16>().offset(wide_index as isize)
}
}; };
Some(address.write(wide_pal8bpp)) Some(address.write(wide_pal8bpp))
} else { } else {
@ -190,7 +189,7 @@ impl Mode4 {
pub fn clear_page_to(page1: bool, pal8bpp: u8) { pub fn clear_page_to(page1: bool, pal8bpp: u8) {
let pal8bpp_32 = pal8bpp as u32; let pal8bpp_32 = pal8bpp as u32;
let bulk_color = (pal8bpp_32 << 24) | (pal8bpp_32 << 16) | (pal8bpp_32 << 8) | pal8bpp_32; let bulk_color = (pal8bpp_32 << 24) | (pal8bpp_32 << 16) | (pal8bpp_32 << 8) | pal8bpp_32;
for va in if page1 { Self::BULK_ITER1 } else { Self::BULK_ITER0 } { for va in (if page1 { Self::PAGE1_BULK32 } else { Self::PAGE0_BULK32 }).iter() {
va.write(bulk_color) va.write(bulk_color)
} }
} }
@ -238,22 +237,16 @@ impl Mode5 {
const SCREEN_U32_COUNT: usize = Self::SCREEN_PIXEL_COUNT / 2; const SCREEN_U32_COUNT: usize = Self::SCREEN_PIXEL_COUNT / 2;
// TODO: newtype this? // TODO: newtype this?
const PAGE0_BASE: VolAddress<Color> = unsafe { VolAddress::new_unchecked(VRAM_BASE_USIZE) }; const PAGE0_BLOCK: VolBlock<Color, <U160 as Mul<U128>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
// TODO: newtype this? // TODO: newtype this?
const PAGE0_BLOCK: VolAddressBlock<Color> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE0_BASE, Self::SCREEN_PIXEL_COUNT) }; const PAGE1_BLOCK: VolBlock<Color, <U160 as Mul<U128>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE + 0xA000) };
// TODO: newtype this?
const PAGE1_BASE: VolAddress<Color> = unsafe { VolAddress::new_unchecked(VRAM_BASE_USIZE + 0xA000) };
// TODO: newtype this?
const PAGE1_BLOCK: VolAddressBlock<Color> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE1_BASE, Self::SCREEN_PIXEL_COUNT) };
/// private iterator over the page0 pixels, four at a time /// private iterator over the page0 pixels, four at a time
const BULK_ITER0: VolAddressIter<u32> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE0_BASE.cast::<u32>(), Self::SCREEN_U32_COUNT).iter() }; const PAGE0_BULK32: VolBlock<u32, <<U160 as Mul<U128>>::Output as Div<U2>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
/// private iterator over the page1 pixels, four at a time /// private iterator over the page1 pixels, four at a time
const BULK_ITER1: VolAddressIter<u32> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE1_BASE.cast::<u32>(), Self::SCREEN_U32_COUNT).iter() }; const PAGE1_BULK32: VolBlock<u32, <<U160 as Mul<U128>>::Output as Div<U2>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE + 0xA000) };
/// Reads the pixel at the given (col,row). /// Reads the pixel at the given (col,row).
/// ///
@ -285,7 +278,7 @@ impl Mode5 {
pub fn clear_page_to(page1: bool, color: Color) { pub fn clear_page_to(page1: bool, color: Color) {
let color32 = color.0 as u32; let color32 = color.0 as u32;
let bulk_color = color32 << 16 | color32; let bulk_color = color32 << 16 | color32;
for va in if page1 { Self::BULK_ITER1 } else { Self::BULK_ITER0 } { for va in (if page1 { Self::PAGE1_BULK32 } else { Self::PAGE0_BULK32 }).iter() {
va.write(bulk_color) va.write(bulk_color)
} }
} }