mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-23 19:01:30 +11:00
Convert to using the recently split off voladdress
lib
This commit is contained in:
parent
dcd7e40b15
commit
fc642c064d
|
@ -146,7 +146,7 @@ So, again using the `hello_magic` example, we had
|
|||
And instead we could declare
|
||||
|
||||
```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
|
||||
|
@ -300,7 +300,7 @@ Now we can have something like:
|
|||
```rust
|
||||
const OTHER_MAGIC: VolAddressBlock<u16> = unsafe {
|
||||
VolAddressBlock::new_unchecked(
|
||||
VolAddress::new_unchecked(0x600_0000),
|
||||
VolAddress::new(0x600_0000),
|
||||
240 * 160
|
||||
)
|
||||
};
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
use super::*;
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
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.
|
||||
pub const BG3CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new_unchecked(0x400_000E) };
|
||||
pub const BG3CNT: VolAddress<BackgroundControlSetting> = unsafe { VolAddress::new(0x400_000E) };
|
||||
|
||||
newtype! {
|
||||
/// Allows configuration of a background layer.
|
||||
|
@ -66,24 +66,24 @@ pub enum BGSize {
|
|||
}
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
pub const BG3VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_001E) };
|
||||
pub const BG3VOFS: VolAddress<u16> = unsafe { VolAddress::new(0x400_001E) };
|
||||
|
||||
// TODO: affine backgrounds
|
||||
// BG2X_L
|
||||
|
@ -100,14 +100,14 @@ pub const BG3VOFS: VolAddress<u16> = unsafe { VolAddress::new_unchecked(0x400_00
|
|||
// 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) };
|
||||
// pub const WIN0H: VolAddress<u16> = unsafe { VolAddress::new(0x400_0040) };
|
||||
// pub const WIN1H: VolAddress<u16> = unsafe { VolAddress::new(0x400_0042) };
|
||||
// pub const WIN0V: VolAddress<u16> = unsafe { VolAddress::new(0x400_0044) };
|
||||
// pub const WIN1V: VolAddress<u16> = unsafe { VolAddress::new(0x400_0046) };
|
||||
// pub const WININ: VolAddress<u16> = unsafe { VolAddress::new(0x400_0048) };
|
||||
// pub const WINOUT: VolAddress<u16> = unsafe { VolAddress::new(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) };
|
||||
// pub const BLDCNT: VolAddress<u16> = unsafe { VolAddress::new(0x400_0050) };
|
||||
// pub const BLDALPHA: VolAddress<u16> = unsafe { VolAddress::new(0x400_0052) };
|
||||
// pub const BLDY: VolAddress<u16> = unsafe { VolAddress::new(0x400_0054) };
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use super::*;
|
||||
|
||||
/// 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! {
|
||||
ColorEffectSetting, u16
|
||||
|
@ -37,7 +37,7 @@ newtype_enum! {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
AlphaBlendingSetting, u16
|
||||
|
@ -52,7 +52,7 @@ impl AlphaBlendingSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
BrightnessSetting, u32
|
||||
|
|
|
@ -5,7 +5,7 @@ use super::*;
|
|||
/// LCD Control. Read/Write.
|
||||
///
|
||||
/// 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!(
|
||||
/// Setting for the display control register.
|
||||
|
@ -96,7 +96,7 @@ pub fn display_control() -> DisplayControlSetting {
|
|||
}
|
||||
|
||||
/// 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!(
|
||||
/// 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
|
||||
/// this is at or above the `VBLANK_SCANLINE` value then the display controller
|
||||
/// 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.
|
||||
pub const VBLANK_SCANLINE: u16 = 160;
|
||||
|
@ -145,7 +145,7 @@ pub fn spin_until_vdraw() {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
/// Allows control of the Mosaic effect.
|
||||
|
|
|
@ -127,13 +127,13 @@ pub enum DMAStartTiming {
|
|||
pub struct DMA0;
|
||||
impl DMA0 {
|
||||
/// 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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
///
|
||||
|
@ -188,13 +188,13 @@ impl DMA0 {
|
|||
pub struct DMA1;
|
||||
impl DMA1 {
|
||||
/// 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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
///
|
||||
|
@ -249,13 +249,13 @@ impl DMA1 {
|
|||
pub struct DMA2;
|
||||
impl DMA2 {
|
||||
/// 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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
///
|
||||
|
@ -311,13 +311,13 @@ impl DMA2 {
|
|||
pub struct DMA3;
|
||||
impl DMA3 {
|
||||
/// 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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
///
|
||||
|
|
|
@ -8,7 +8,7 @@ use super::*;
|
|||
/// 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
|
||||
/// 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.
|
||||
#[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.
|
||||
///
|
||||
/// 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! {
|
||||
/// Allows configuration of when a keypad interrupt fires.
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::*;
|
|||
//TODO within these "read/write" registers only some bits are actually 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! {
|
||||
SweepRegisterSetting, u16
|
||||
|
@ -20,7 +20,7 @@ impl SweepRegisterSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
DutyLenEnvelopeSetting, u16
|
||||
|
@ -38,7 +38,7 @@ impl DutyLenEnvelopeSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
FrequencyControlSetting, u32 // TODO: u16 or u32?
|
||||
|
@ -54,13 +54,13 @@ impl FrequencyControlSetting {
|
|||
}
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
pub const SOUND3CNT_L: VolAddress<StopWaveRAMSelectSetting> = unsafe { VolAddress::new_unchecked(0x400_0070) };
|
||||
pub const SOUND3CNT_L: VolAddress<StopWaveRAMSelectSetting> = unsafe { VolAddress::new(0x400_0070) };
|
||||
|
||||
newtype! {
|
||||
StopWaveRAMSelectSetting, u16
|
||||
|
@ -76,7 +76,7 @@ impl StopWaveRAMSelectSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
LengthVolumeSetting, u16
|
||||
|
@ -92,27 +92,27 @@ impl LengthVolumeSetting {
|
|||
}
|
||||
|
||||
/// 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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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.
|
||||
pub const SOUND4CNT_L: VolAddress<LengthEnvelopeSetting> = unsafe { VolAddress::new_unchecked(0x400_0078) };
|
||||
pub const SOUND4CNT_L: VolAddress<LengthEnvelopeSetting> = unsafe { VolAddress::new(0x400_0078) };
|
||||
|
||||
newtype! {
|
||||
LengthEnvelopeSetting, u32 // TODO: is this u32?
|
||||
|
@ -129,7 +129,7 @@ impl LengthEnvelopeSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
NoiseFrequencySetting, u32 // TODO: is this u32?
|
||||
|
@ -149,16 +149,16 @@ impl NoiseFrequencySetting {
|
|||
// TODO: unify FIFO as
|
||||
|
||||
/// 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)
|
||||
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)
|
||||
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)
|
||||
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.
|
||||
pub const SOUNDCNT_L: VolAddress<NonWaveVolumeEnableSetting> = unsafe { VolAddress::new_unchecked(0x400_0080) };
|
||||
pub const SOUNDCNT_L: VolAddress<NonWaveVolumeEnableSetting> = unsafe { VolAddress::new(0x400_0080) };
|
||||
|
||||
newtype! {
|
||||
NonWaveVolumeEnableSetting, u16
|
||||
|
@ -175,7 +175,7 @@ impl NonWaveVolumeEnableSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
WaveVolumeEnableSetting, u16
|
||||
|
@ -206,7 +206,7 @@ newtype_enum! {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
SoundMasterSetting, u16
|
||||
|
@ -224,7 +224,7 @@ impl SoundMasterSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
SoundPWMSetting, u16
|
||||
|
|
|
@ -28,28 +28,28 @@ use super::*;
|
|||
// TODO: striding blocks?
|
||||
|
||||
/// 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).
|
||||
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).
|
||||
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).
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
pub const TM3CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new_unchecked(0x400_010E) };
|
||||
pub const TM3CNT_H: VolAddress<TimerControlSetting> = unsafe { VolAddress::new(0x400_010E) };
|
||||
|
||||
newtype! {
|
||||
/// Allows control of a timer unit.
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
use super::*;
|
||||
|
||||
/// 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)
|
||||
pub const WIN1H: VolAddress<HorizontalWindowSetting> = unsafe { VolAddress::new_unchecked(0x400_0042) };
|
||||
pub const WIN1H: VolAddress<HorizontalWindowSetting> = unsafe { VolAddress::new(0x400_0042) };
|
||||
|
||||
newtype! {
|
||||
HorizontalWindowSetting, u16
|
||||
|
@ -21,10 +21,10 @@ impl HorizontalWindowSetting {
|
|||
}
|
||||
|
||||
/// 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)
|
||||
pub const WIN1V: VolAddress<VerticalWindowSetting> = unsafe { VolAddress::new_unchecked(0x400_0046) };
|
||||
pub const WIN1V: VolAddress<VerticalWindowSetting> = unsafe { VolAddress::new(0x400_0046) };
|
||||
|
||||
newtype! {
|
||||
VerticalWindowSetting, u16
|
||||
|
@ -39,7 +39,7 @@ impl VerticalWindowSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
InsideWindowSetting, u16
|
||||
|
@ -64,7 +64,7 @@ impl InsideWindowSetting {
|
|||
}
|
||||
|
||||
/// 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! {
|
||||
OutsideWindowSetting, u16
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
//! do, it's a giant bag of Undefined Behavior.
|
||||
|
||||
pub(crate) use gba_proc_macro::phantom_fields;
|
||||
pub(crate) use voladdress::{VolAddress, VolBlock};
|
||||
|
||||
/// Assists in defining a newtype wrapper over some base type.
|
||||
///
|
||||
|
@ -105,7 +106,6 @@ macro_rules! newtype_enum {
|
|||
}
|
||||
|
||||
pub mod base;
|
||||
pub(crate) use self::base::*;
|
||||
|
||||
pub mod bios;
|
||||
|
||||
|
|
|
@ -24,13 +24,13 @@ pub struct MGBADebug {
|
|||
bytes_written: u8,
|
||||
}
|
||||
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_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;
|
||||
|
||||
/// Gives a new MGBADebug, if running within `mGBA`
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
use super::*;
|
||||
|
||||
use typenum::consts::{U128, U32};
|
||||
|
||||
newtype! {
|
||||
/// 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
|
||||
/// 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<()> {
|
||||
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
|
||||
/// 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<()> {
|
||||
AFFINE_PARAMS_APPROX.get(slot).map(|va| unsafe {
|
||||
|
|
|
@ -23,18 +23,17 @@
|
|||
//! display will show if no background or object draws over top of a given pixel
|
||||
//! during rendering.
|
||||
|
||||
use super::{
|
||||
base::volatile::{VolAddress, VolAddressBlock},
|
||||
Color,
|
||||
};
|
||||
use super::*;
|
||||
|
||||
use typenum::consts::U256;
|
||||
|
||||
// TODO: PalIndex newtypes?
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
pub const fn index_palram_bg_8bpp(slot: u8) -> VolAddress<Color> {
|
||||
|
|
15
src/vram.rs
15
src/vram.rs
|
@ -15,6 +15,8 @@
|
|||
|
||||
pub(crate) use super::*;
|
||||
|
||||
use typenum::consts::{U256, U32, U512, U6};
|
||||
|
||||
pub mod affine;
|
||||
pub mod bitmap;
|
||||
pub mod text;
|
||||
|
@ -28,11 +30,10 @@ pub mod text;
|
|||
pub const VRAM_BASE_USIZE: usize = 0x600_0000;
|
||||
|
||||
/// 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.
|
||||
pub const SCREEN_BASE_BLOCKS: VolAddressBlock<[u8; 0x800]> =
|
||||
unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(VRAM_BASE_USIZE), 32) };
|
||||
pub const SCREEN_BASE_BLOCKS: VolBlock<[u8; 0x800], U32> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
|
||||
|
||||
newtype! {
|
||||
/// An 8x8 tile with 4bpp, packed as `u32` values for proper alignment.
|
||||
|
@ -47,11 +48,11 @@ newtype! {
|
|||
}
|
||||
|
||||
/// Gives the specified charblock in 4bpp view.
|
||||
pub fn get_4bpp_character_block(slot: usize) -> VolAddressBlock<Tile4bpp> {
|
||||
unsafe { VolAddressBlock::new_unchecked(CHAR_BASE_BLOCKS.index(slot).cast::<Tile4bpp>(), 512) }
|
||||
pub fn get_4bpp_character_block(slot: usize) -> VolBlock<Tile4bpp, U512> {
|
||||
unsafe { VolBlock::new(CHAR_BASE_BLOCKS.index(slot).to_usize()) }
|
||||
}
|
||||
|
||||
/// Gives the specified charblock in 8bpp view.
|
||||
pub fn get_8bpp_character_block(slot: usize) -> VolAddressBlock<Tile8bpp> {
|
||||
unsafe { VolAddressBlock::new_unchecked(CHAR_BASE_BLOCKS.index(slot).cast::<Tile8bpp>(), 256) }
|
||||
pub fn get_8bpp_character_block(slot: usize) -> VolBlock<Tile8bpp, U256> {
|
||||
unsafe { VolBlock::new(CHAR_BASE_BLOCKS.index(slot).to_usize()) }
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
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.
|
||||
///
|
||||
/// * **Width:** 240
|
||||
|
@ -27,12 +30,10 @@ impl Mode3 {
|
|||
///
|
||||
/// Use `col + row * SCREEN_WIDTH` to get the address of an individual pixel,
|
||||
/// or use the helpers provided in this module.
|
||||
pub const VRAM: VolAddressBlock<Color> =
|
||||
unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(VRAM_BASE_USIZE), Self::SCREEN_PIXEL_COUNT) };
|
||||
pub const VRAM: VolBlock<Color, <U256 as Mul<U160>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
|
||||
|
||||
/// private iterator over the pixels, two at a time
|
||||
const BULK_ITER: VolAddressIter<u32> =
|
||||
unsafe { VolAddressBlock::new_unchecked(VolAddress::new_unchecked(VRAM_BASE_USIZE), Self::SCREEN_PIXEL_COUNT / 2).iter() };
|
||||
const VRAM_BULK: VolBlock<u32, <<U256 as Mul<U160>>::Output as Div<U2>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE) };
|
||||
|
||||
/// Reads the pixel at the given (col,row).
|
||||
///
|
||||
|
@ -56,7 +57,7 @@ impl Mode3 {
|
|||
pub fn clear_to(color: Color) {
|
||||
let color32 = color.0 as u32;
|
||||
let bulk_color = color32 << 16 | color32;
|
||||
for va in Self::BULK_ITER {
|
||||
for va in Self::VRAM_BULK.iter() {
|
||||
va.write(bulk_color)
|
||||
}
|
||||
}
|
||||
|
@ -101,22 +102,22 @@ impl Mode4 {
|
|||
const SCREEN_U32_COUNT: usize = Self::SCREEN_PIXEL_COUNT / 4;
|
||||
|
||||
// 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?
|
||||
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?
|
||||
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?
|
||||
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
|
||||
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
|
||||
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).
|
||||
///
|
||||
|
@ -126,9 +127,9 @@ impl Mode4 {
|
|||
pub fn read_pixel(page1: bool, col: usize, row: usize) -> Option<u8> {
|
||||
// Note(Lokathor): byte _reads_ from VRAM are okay.
|
||||
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 {
|
||||
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 address: VolAddress<u16> = unsafe {
|
||||
if page1 {
|
||||
Self::PAGE1_BASE.offset(rounded_down_index as isize).cast()
|
||||
Self::PAGE1_BLOCK8.index(rounded_down_index).cast()
|
||||
} 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 {
|
||||
|
@ -173,12 +174,10 @@ impl Mode4 {
|
|||
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 {
|
||||
let wide_index = wide_col + row * Self::SCREEN_WIDTH / 2;
|
||||
let address: VolAddress<u16> = unsafe {
|
||||
if page1 {
|
||||
Self::PAGE1_BASE.cast::<u16>().offset(wide_index as isize)
|
||||
let address: VolAddress<u16> = if page1 {
|
||||
Self::PAGE1_BLOCK16.index(wide_index)
|
||||
} else {
|
||||
Self::PAGE0_BASE.cast::<u16>().offset(wide_index as isize)
|
||||
}
|
||||
Self::PAGE0_BLOCK16.index(wide_index)
|
||||
};
|
||||
Some(address.write(wide_pal8bpp))
|
||||
} else {
|
||||
|
@ -190,7 +189,7 @@ impl Mode4 {
|
|||
pub fn clear_page_to(page1: bool, pal8bpp: u8) {
|
||||
let pal8bpp_32 = pal8bpp as u32;
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -238,22 +237,16 @@ impl Mode5 {
|
|||
const SCREEN_U32_COUNT: usize = Self::SCREEN_PIXEL_COUNT / 2;
|
||||
|
||||
// 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?
|
||||
const PAGE0_BLOCK: VolAddressBlock<Color> = unsafe { VolAddressBlock::new_unchecked(Self::PAGE0_BASE, Self::SCREEN_PIXEL_COUNT) };
|
||||
|
||||
// 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) };
|
||||
const PAGE1_BLOCK: VolBlock<Color, <U160 as Mul<U128>>::Output> = unsafe { VolBlock::new(VRAM_BASE_USIZE + 0xA000) };
|
||||
|
||||
/// 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
|
||||
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).
|
||||
///
|
||||
|
@ -285,7 +278,7 @@ impl Mode5 {
|
|||
pub fn clear_page_to(page1: bool, color: Color) {
|
||||
let color32 = color.0 as u32;
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue