mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-24 03:11:29 +11:00
Move to the phantom_fields!
proc-macro
This commit is contained in:
parent
bee2d16a5b
commit
6466a53475
|
@ -13,7 +13,7 @@ publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
typenum = "1.10"
|
typenum = "1.10"
|
||||||
gba-proc-macro = "0.4.1"
|
gba-proc-macro = "0.5"
|
||||||
|
|
||||||
#[dev-dependencies]
|
#[dev-dependencies]
|
||||||
#quickcheck="0.7"
|
#quickcheck="0.7"
|
||||||
|
|
|
@ -29,8 +29,8 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
set_bg_tile_4bpp(0, 0, ALL_TWOS);
|
set_bg_tile_4bpp(0, 0, ALL_TWOS);
|
||||||
set_bg_tile_4bpp(0, 1, ALL_THREES);
|
set_bg_tile_4bpp(0, 1, ALL_THREES);
|
||||||
// screenblock
|
// screenblock
|
||||||
let light_entry = TextScreenblockEntry::from_tile_index(0);
|
let light_entry = TextScreenblockEntry::from_tile_id(0);
|
||||||
let dark_entry = TextScreenblockEntry::from_tile_index(1);
|
let dark_entry = TextScreenblockEntry::from_tile_id(1);
|
||||||
checker_screenblock(8, light_entry, dark_entry);
|
checker_screenblock(8, light_entry, dark_entry);
|
||||||
// bg0 control
|
// bg0 control
|
||||||
BG0CNT.write(BackgroundControlSetting::new().with_screen_base_block(8));
|
BG0CNT.write(BackgroundControlSetting::new().with_screen_base_block(8));
|
||||||
|
|
26
src/bios.rs
26
src/bios.rs
|
@ -8,7 +8,7 @@
|
||||||
//! whatever value is necessary for that function). Some functions also perform
|
//! whatever value is necessary for that function). Some functions also perform
|
||||||
//! necessary checks to save you from yourself, such as not dividing by zero.
|
//! necessary checks to save you from yourself, such as not dividing by zero.
|
||||||
|
|
||||||
use super::bool_bits;
|
use super::*;
|
||||||
|
|
||||||
//TODO: ALL functions in this module should have `if cfg!(test)` blocks. The
|
//TODO: ALL functions in this module should have `if cfg!(test)` blocks. The
|
||||||
//functions that never return must panic, the functions that return nothing
|
//functions that never return must panic, the functions that return nothing
|
||||||
|
@ -109,19 +109,17 @@ newtype! {
|
||||||
}
|
}
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
impl RegisterRAMResetFlags {
|
impl RegisterRAMResetFlags {
|
||||||
bool_bits!(
|
phantom_fields! {
|
||||||
u8,
|
self.0: u8,
|
||||||
[
|
ewram: 0,
|
||||||
(0, ewram),
|
iwram: 1,
|
||||||
(1, iwram),
|
palram: 2,
|
||||||
(2, palram),
|
vram: 3,
|
||||||
(3, vram),
|
oam: 4,
|
||||||
(4, oam),
|
sio: 5,
|
||||||
(5, sio),
|
sound: 6,
|
||||||
(6, sound),
|
other_io: 7,
|
||||||
(7, other_io),
|
}
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// (`swi 0x02`) Halts the CPU until an interrupt occurs.
|
/// (`swi 0x02`) Halts the CPU until an interrupt occurs.
|
||||||
|
|
|
@ -25,17 +25,16 @@ newtype! {
|
||||||
BackgroundControlSetting, u16
|
BackgroundControlSetting, u16
|
||||||
}
|
}
|
||||||
impl BackgroundControlSetting {
|
impl BackgroundControlSetting {
|
||||||
bool_bits!(u16, [(6, mosaic), (7, is_8bpp), (13, display_overflow_wrapping)]);
|
phantom_fields! {
|
||||||
|
self.0: u16,
|
||||||
multi_bits!(
|
bg_priority: 0-1,
|
||||||
u16,
|
char_base_block: 2-3,
|
||||||
[
|
mosaic: 6,
|
||||||
(0, 2, bg_priority),
|
is_8bpp: 7,
|
||||||
(2, 2, char_base_block),
|
screen_base_block: 8-12,
|
||||||
(8, 5, screen_base_block),
|
affine_display_overflow_wrapping: 13,
|
||||||
(2, 2, size, BGSize, Zero, One, Two, Three),
|
size: 14-15=BGSize<Zero, One, Two, Three>,
|
||||||
]
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The size of a background.
|
/// The size of a background.
|
||||||
|
|
|
@ -31,26 +31,23 @@ newtype!(
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
impl DisplayControlSetting {
|
impl DisplayControlSetting {
|
||||||
bool_bits!(
|
phantom_fields! {
|
||||||
u16,
|
self.0: u16,
|
||||||
[
|
mode: 0-2=DisplayMode<Mode0, Mode1, Mode2, Mode3, Mode4, Mode5>,
|
||||||
(3, cgb_mode),
|
cgb_mode: 3,
|
||||||
(4, frame1),
|
frame1: 4,
|
||||||
(5, hblank_interval_free),
|
hblank_interval_free: 5,
|
||||||
(6, oam_memory_1d),
|
oam_memory_1d: 6,
|
||||||
(7, force_vblank),
|
force_vblank: 7,
|
||||||
(8, bg0),
|
bg0: 8,
|
||||||
(9, bg1),
|
bg1: 9,
|
||||||
(10, bg2),
|
bg2: 10,
|
||||||
(11, bg3),
|
bg3: 11,
|
||||||
(12, obj),
|
obj: 12,
|
||||||
(13, win0),
|
win0: 13,
|
||||||
(14, win1),
|
win1: 14,
|
||||||
(15, obj_window)
|
obj_window: 15,
|
||||||
]
|
}
|
||||||
);
|
|
||||||
|
|
||||||
multi_bits!(u16, [(0, 3, mode, DisplayMode, Mode0, Mode1, Mode2, Mode3, Mode4, Mode5)]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The six display modes available on the GBA.
|
/// The six display modes available on the GBA.
|
||||||
|
@ -113,19 +110,16 @@ newtype!(
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
impl DisplayStatusSetting {
|
impl DisplayStatusSetting {
|
||||||
bool_bits!(
|
phantom_fields! {
|
||||||
u16,
|
self.0: u16,
|
||||||
[
|
vblank_flag: 0,
|
||||||
(0, vblank_flag),
|
hblank_flag: 1,
|
||||||
(1, hblank_flag),
|
vcounter_flag: 2,
|
||||||
(2, vcounter_flag),
|
vblank_irq_enable: 3,
|
||||||
(3, vblank_irq_enable),
|
hblank_irq_enable: 4,
|
||||||
(4, hblank_irq_enable),
|
vcounter_irq_enable: 5,
|
||||||
(5, vcounter_irq_enable),
|
vcount_setting: 8-15,
|
||||||
]
|
}
|
||||||
);
|
|
||||||
|
|
||||||
multi_bits!(u16, [(8, 8, vcount_setting)]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Vertical Counter (LY). Read only.
|
/// Vertical Counter (LY). Read only.
|
||||||
|
@ -178,13 +172,11 @@ newtype! {
|
||||||
MosaicSetting, u16
|
MosaicSetting, u16
|
||||||
}
|
}
|
||||||
impl MosaicSetting {
|
impl MosaicSetting {
|
||||||
multi_bits!(
|
phantom_fields! {
|
||||||
u16,
|
self.0: u16,
|
||||||
[
|
bg_horizontal_inc: 0-3,
|
||||||
(0, 4, bg_horizontal_inc),
|
bg_vertical_inc: 4-7,
|
||||||
(4, 4, bg_vertical_inc),
|
obj_horizontal_inc: 8-11,
|
||||||
(8, 4, obj_horizontal_inc),
|
obj_vertical_inc: 12-15,
|
||||||
(12, 4, obj_vertical_inc),
|
}
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,25 +68,16 @@ newtype! {
|
||||||
}
|
}
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
impl DMAControlSetting {
|
impl DMAControlSetting {
|
||||||
bool_bits!(u16, [(9, dma_repeat), (10, use_32bit), (14, irq_when_done), (15, enabled)]);
|
phantom_fields! {
|
||||||
|
self.0: u16,
|
||||||
multi_bits!(
|
dest_address_control: 5-6=DMADestAddressControl<Increment, Decrement, Fixed, IncrementReload>,
|
||||||
u16,
|
source_address_control: 7-8=DMASrcAddressControl<Increment, Decrement, Fixed>,
|
||||||
[
|
dma_repeat: 9,
|
||||||
(
|
use_32bit: 10,
|
||||||
5,
|
start_time: 12-13=DMAStartTiming<Immediate, VBlank, HBlank, Special>,
|
||||||
2,
|
irq_when_done: 14,
|
||||||
dest_address_control,
|
enabled: 15,
|
||||||
DMADestAddressControl,
|
}
|
||||||
Increment,
|
|
||||||
Decrement,
|
|
||||||
Fixed,
|
|
||||||
IncrementReload
|
|
||||||
),
|
|
||||||
(7, 2, source_address_control, DMASrcAddressControl, Increment, Decrement, Fixed),
|
|
||||||
(12, 2, start_time, DMAStartTiming, Immediate, VBlank, HBlank, Special)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets how the destination address should be adjusted per data transfer.
|
/// Sets how the destination address should be adjusted per data transfer.
|
||||||
|
|
|
@ -33,21 +33,19 @@ newtype! {
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
impl KeyInput {
|
impl KeyInput {
|
||||||
bool_bits!(
|
phantom_fields! {
|
||||||
u16,
|
self.0: u16,
|
||||||
[
|
a: 0,
|
||||||
(0, a),
|
b: 1,
|
||||||
(1, b),
|
select: 2,
|
||||||
(2, select),
|
start: 3,
|
||||||
(3, start),
|
right: 4,
|
||||||
(4, right),
|
left: 5,
|
||||||
(5, left),
|
up: 6,
|
||||||
(6, up),
|
down: 7,
|
||||||
(7, down),
|
r: 8,
|
||||||
(8, r),
|
l: 9,
|
||||||
(9, l)
|
}
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Takes the set difference between these keys and another set of keys.
|
/// Takes the set difference between these keys and another set of keys.
|
||||||
pub fn difference(self, other: Self) -> Self {
|
pub fn difference(self, other: Self) -> Self {
|
||||||
|
@ -107,23 +105,21 @@ newtype! {
|
||||||
}
|
}
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
impl KeyInterruptSetting {
|
impl KeyInterruptSetting {
|
||||||
bool_bits!(
|
phantom_fields! {
|
||||||
u16,
|
self.0: u16,
|
||||||
[
|
a: 0,
|
||||||
(0, a),
|
b: 1,
|
||||||
(1, b),
|
select: 2,
|
||||||
(2, select),
|
start: 3,
|
||||||
(3, start),
|
right: 4,
|
||||||
(4, right),
|
left: 5,
|
||||||
(5, left),
|
up: 6,
|
||||||
(6, up),
|
down: 7,
|
||||||
(7, down),
|
r: 8,
|
||||||
(8, r),
|
l: 9,
|
||||||
(9, l),
|
irq_enabled: 14,
|
||||||
(14, irq_enabled),
|
irq_logical_and: 15,
|
||||||
(15, irq_logical_and)
|
}
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use this to configure when a keypad interrupt happens.
|
/// Use this to configure when a keypad interrupt happens.
|
||||||
|
|
|
@ -65,9 +65,12 @@ newtype! {
|
||||||
TimerControlSetting, u16
|
TimerControlSetting, u16
|
||||||
}
|
}
|
||||||
impl TimerControlSetting {
|
impl TimerControlSetting {
|
||||||
bool_bits!(u16, [(6, overflow_irq), (7, enabled)]);
|
phantom_fields! {
|
||||||
|
self.0: u16,
|
||||||
multi_bits!(u16, [(0, 3, tick_rate, TimerTickRate, CPU1, CPU64, CPU256, CPU1024, Cascade),]);
|
tick_rate: 0-2=TimerTickRate<CPU1, CPU64, CPU256, CPU1024, Cascade>,
|
||||||
|
overflow_irq: 6,
|
||||||
|
enabled: 7,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Controls how often an enabled timer ticks upward.
|
/// Controls how often an enabled timer ticks upward.
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
//! **Do not** use this crate in programs that aren't running on the GBA. If you
|
//! **Do not** use this crate in programs that aren't running on the GBA. If you
|
||||||
//! do, it's a giant bag of Undefined Behavior.
|
//! do, it's a giant bag of Undefined Behavior.
|
||||||
|
|
||||||
pub(crate) use gba_proc_macro::{bool_bits, multi_bits};
|
pub(crate) use gba_proc_macro::phantom_fields;
|
||||||
|
|
||||||
/// Assists in defining a newtype wrapper over some base type.
|
/// Assists in defining a newtype wrapper over some base type.
|
||||||
///
|
///
|
||||||
|
|
45
src/oam.rs
45
src/oam.rs
|
@ -15,17 +15,15 @@ newtype! {
|
||||||
OBJAttr0, u16
|
OBJAttr0, u16
|
||||||
}
|
}
|
||||||
impl OBJAttr0 {
|
impl OBJAttr0 {
|
||||||
bool_bits!(u16, [(12, mosaic), (13, is_8bpp),]);
|
phantom_fields! {
|
||||||
|
self.0: u16,
|
||||||
multi_bits!(
|
row_coordinate: 0-7,
|
||||||
u16,
|
obj_rendering: 8-9=ObjectRender<Normal, Affine, Disabled, DoubleAreaAffine>,
|
||||||
[
|
obj_mode: 10-11=ObjectMode<Normal, SemiTransparent, OBJWindow>,
|
||||||
(0, 8, row_coordinate),
|
mosaic: 12,
|
||||||
(8, 2, obj_rendering, ObjectRender, Normal, Affine, Disabled, DoubleAreaAffine),
|
is_8bpp: 13,
|
||||||
(10, 2, obj_mode, ObjectMode, Normal, SemiTransparent, OBJWindow),
|
obj_shape: 14-15=ObjectShape<Square, Horizontal, Vertical>,
|
||||||
(14, 2, obj_shape, ObjectShape, Square, Horizontal, Vertical),
|
}
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What style of rendering for this object
|
/// What style of rendering for this object
|
||||||
|
@ -81,16 +79,14 @@ newtype! {
|
||||||
OBJAttr1, u16
|
OBJAttr1, u16
|
||||||
}
|
}
|
||||||
impl OBJAttr1 {
|
impl OBJAttr1 {
|
||||||
bool_bits!(u16, [(12, hflip), (13, vflip),]);
|
phantom_fields! {
|
||||||
|
self.0: u16,
|
||||||
multi_bits!(
|
col_coordinate: 0-8,
|
||||||
u16,
|
affine_index: 9-13,
|
||||||
[
|
hflip: 12,
|
||||||
(0, 9, col_coordinate),
|
vflip: 13,
|
||||||
(9, 5, affine_index),
|
obj_size: 14-15=ObjectSize<Zero, One, Two, Three>,
|
||||||
(14, 2, obj_size, ObjectSize, Zero, One, Two, Three),
|
}
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The object's size.
|
/// The object's size.
|
||||||
|
@ -127,5 +123,10 @@ newtype! {
|
||||||
OBJAttr2, u16
|
OBJAttr2, u16
|
||||||
}
|
}
|
||||||
impl OBJAttr2 {
|
impl OBJAttr2 {
|
||||||
multi_bits!(u16, [(0, 10, tile_id), (10, 2, priority), (12, 4, palbank),]);
|
phantom_fields! {
|
||||||
|
self.0: u16,
|
||||||
|
tile_id: 0-9,
|
||||||
|
priority: 10-11,
|
||||||
|
palbank: 12-15,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,17 @@ newtype! {
|
||||||
}
|
}
|
||||||
impl TextScreenblockEntry {
|
impl TextScreenblockEntry {
|
||||||
/// Generates a default entry with the specified tile index.
|
/// Generates a default entry with the specified tile index.
|
||||||
pub const fn from_tile_index(index: u16) -> Self {
|
pub const fn from_tile_id(id: u16) -> Self {
|
||||||
Self::new().with_tile_index(index)
|
Self::new().with_tile_id(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_bits!(u16, [(10, hflip), (11, vflip)]);
|
phantom_fields! {
|
||||||
|
self.0: u16,
|
||||||
multi_bits!(u16, [(0, 10, tile_index), (12, 4, palbank)]);
|
tile_id: 0-9,
|
||||||
|
hflip: 10,
|
||||||
|
vflip: 11,
|
||||||
|
palbank: 12-15,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newtype! {
|
newtype! {
|
||||||
|
|
Loading…
Reference in a new issue