From 6466a5347512ed003cb023021056ef49925d546a Mon Sep 17 00:00:00 2001 From: Lokathor Date: Sat, 29 Dec 2018 00:06:08 -0700 Subject: [PATCH 1/9] Move to the `phantom_fields!` proc-macro --- Cargo.toml | 2 +- examples/bg_demo.rs | 4 +-- src/bios.rs | 26 +++++++-------- src/io/background.rs | 21 ++++++------ src/io/display.rs | 76 ++++++++++++++++++++------------------------ src/io/dma.rs | 29 ++++++----------- src/io/keypad.rs | 60 ++++++++++++++++------------------ src/io/timers.rs | 9 ++++-- src/lib.rs | 2 +- src/oam.rs | 45 +++++++++++++------------- src/vram/text.rs | 14 +++++--- 11 files changed, 136 insertions(+), 152 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eafa519..2e7a2d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ publish = false [dependencies] typenum = "1.10" -gba-proc-macro = "0.4.1" +gba-proc-macro = "0.5" #[dev-dependencies] #quickcheck="0.7" diff --git a/examples/bg_demo.rs b/examples/bg_demo.rs index 472233c..515bd7e 100644 --- a/examples/bg_demo.rs +++ b/examples/bg_demo.rs @@ -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, 1, ALL_THREES); // screenblock - let light_entry = TextScreenblockEntry::from_tile_index(0); - let dark_entry = TextScreenblockEntry::from_tile_index(1); + let light_entry = TextScreenblockEntry::from_tile_id(0); + let dark_entry = TextScreenblockEntry::from_tile_id(1); checker_screenblock(8, light_entry, dark_entry); // bg0 control BG0CNT.write(BackgroundControlSetting::new().with_screen_base_block(8)); diff --git a/src/bios.rs b/src/bios.rs index bfdf0da..ce01862 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -8,7 +8,7 @@ //! whatever value is necessary for that function). Some functions also perform //! 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 //functions that never return must panic, the functions that return nothing @@ -109,19 +109,17 @@ newtype! { } #[allow(missing_docs)] impl RegisterRAMResetFlags { - bool_bits!( - u8, - [ - (0, ewram), - (1, iwram), - (2, palram), - (3, vram), - (4, oam), - (5, sio), - (6, sound), - (7, other_io), - ] - ); + phantom_fields! { + self.0: u8, + ewram: 0, + iwram: 1, + palram: 2, + vram: 3, + oam: 4, + sio: 5, + sound: 6, + other_io: 7, + } } /// (`swi 0x02`) Halts the CPU until an interrupt occurs. diff --git a/src/io/background.rs b/src/io/background.rs index abe1a31..c5df78b 100644 --- a/src/io/background.rs +++ b/src/io/background.rs @@ -25,17 +25,16 @@ newtype! { BackgroundControlSetting, u16 } impl BackgroundControlSetting { - bool_bits!(u16, [(6, mosaic), (7, is_8bpp), (13, display_overflow_wrapping)]); - - multi_bits!( - u16, - [ - (0, 2, bg_priority), - (2, 2, char_base_block), - (8, 5, screen_base_block), - (2, 2, size, BGSize, Zero, One, Two, Three), - ] - ); + phantom_fields! { + self.0: u16, + bg_priority: 0-1, + char_base_block: 2-3, + mosaic: 6, + is_8bpp: 7, + screen_base_block: 8-12, + affine_display_overflow_wrapping: 13, + size: 14-15=BGSize, + } } /// The size of a background. diff --git a/src/io/display.rs b/src/io/display.rs index 421c93b..b5e52ae 100644 --- a/src/io/display.rs +++ b/src/io/display.rs @@ -31,26 +31,23 @@ newtype!( #[allow(missing_docs)] impl DisplayControlSetting { - bool_bits!( - u16, - [ - (3, cgb_mode), - (4, frame1), - (5, hblank_interval_free), - (6, oam_memory_1d), - (7, force_vblank), - (8, bg0), - (9, bg1), - (10, bg2), - (11, bg3), - (12, obj), - (13, win0), - (14, win1), - (15, obj_window) - ] - ); - - multi_bits!(u16, [(0, 3, mode, DisplayMode, Mode0, Mode1, Mode2, Mode3, Mode4, Mode5)]); + phantom_fields! { + self.0: u16, + mode: 0-2=DisplayMode, + cgb_mode: 3, + frame1: 4, + hblank_interval_free: 5, + oam_memory_1d: 6, + force_vblank: 7, + bg0: 8, + bg1: 9, + bg2: 10, + bg3: 11, + obj: 12, + win0: 13, + win1: 14, + obj_window: 15, + } } /// The six display modes available on the GBA. @@ -113,19 +110,16 @@ newtype!( #[allow(missing_docs)] impl DisplayStatusSetting { - bool_bits!( - u16, - [ - (0, vblank_flag), - (1, hblank_flag), - (2, vcounter_flag), - (3, vblank_irq_enable), - (4, hblank_irq_enable), - (5, vcounter_irq_enable), - ] - ); - - multi_bits!(u16, [(8, 8, vcount_setting)]); + phantom_fields! { + self.0: u16, + vblank_flag: 0, + hblank_flag: 1, + vcounter_flag: 2, + vblank_irq_enable: 3, + hblank_irq_enable: 4, + vcounter_irq_enable: 5, + vcount_setting: 8-15, + } } /// Vertical Counter (LY). Read only. @@ -178,13 +172,11 @@ newtype! { MosaicSetting, u16 } impl MosaicSetting { - multi_bits!( - u16, - [ - (0, 4, bg_horizontal_inc), - (4, 4, bg_vertical_inc), - (8, 4, obj_horizontal_inc), - (12, 4, obj_vertical_inc), - ] - ); + phantom_fields! { + self.0: u16, + bg_horizontal_inc: 0-3, + bg_vertical_inc: 4-7, + obj_horizontal_inc: 8-11, + obj_vertical_inc: 12-15, + } } diff --git a/src/io/dma.rs b/src/io/dma.rs index 3ecd98e..7dca8de 100644 --- a/src/io/dma.rs +++ b/src/io/dma.rs @@ -68,25 +68,16 @@ newtype! { } #[allow(missing_docs)] impl DMAControlSetting { - bool_bits!(u16, [(9, dma_repeat), (10, use_32bit), (14, irq_when_done), (15, enabled)]); - - multi_bits!( - u16, - [ - ( - 5, - 2, - dest_address_control, - DMADestAddressControl, - Increment, - Decrement, - Fixed, - IncrementReload - ), - (7, 2, source_address_control, DMASrcAddressControl, Increment, Decrement, Fixed), - (12, 2, start_time, DMAStartTiming, Immediate, VBlank, HBlank, Special) - ] - ); + phantom_fields! { + self.0: u16, + dest_address_control: 5-6=DMADestAddressControl, + source_address_control: 7-8=DMASrcAddressControl, + dma_repeat: 9, + use_32bit: 10, + start_time: 12-13=DMAStartTiming, + irq_when_done: 14, + enabled: 15, + } } /// Sets how the destination address should be adjusted per data transfer. diff --git a/src/io/keypad.rs b/src/io/keypad.rs index 80e5d55..ec24995 100644 --- a/src/io/keypad.rs +++ b/src/io/keypad.rs @@ -33,21 +33,19 @@ newtype! { #[allow(missing_docs)] impl KeyInput { - bool_bits!( - u16, - [ - (0, a), - (1, b), - (2, select), - (3, start), - (4, right), - (5, left), - (6, up), - (7, down), - (8, r), - (9, l) - ] - ); + phantom_fields! { + self.0: u16, + a: 0, + b: 1, + select: 2, + start: 3, + right: 4, + left: 5, + up: 6, + down: 7, + r: 8, + l: 9, + } /// Takes the set difference between these keys and another set of keys. pub fn difference(self, other: Self) -> Self { @@ -107,23 +105,21 @@ newtype! { } #[allow(missing_docs)] impl KeyInterruptSetting { - bool_bits!( - u16, - [ - (0, a), - (1, b), - (2, select), - (3, start), - (4, right), - (5, left), - (6, up), - (7, down), - (8, r), - (9, l), - (14, irq_enabled), - (15, irq_logical_and) - ] - ); + phantom_fields! { + self.0: u16, + a: 0, + b: 1, + select: 2, + start: 3, + right: 4, + left: 5, + up: 6, + down: 7, + r: 8, + l: 9, + irq_enabled: 14, + irq_logical_and: 15, + } } /// Use this to configure when a keypad interrupt happens. diff --git a/src/io/timers.rs b/src/io/timers.rs index 026409e..6086ebe 100644 --- a/src/io/timers.rs +++ b/src/io/timers.rs @@ -65,9 +65,12 @@ newtype! { TimerControlSetting, u16 } impl TimerControlSetting { - bool_bits!(u16, [(6, overflow_irq), (7, enabled)]); - - multi_bits!(u16, [(0, 3, tick_rate, TimerTickRate, CPU1, CPU64, CPU256, CPU1024, Cascade),]); + phantom_fields! { + self.0: u16, + tick_rate: 0-2=TimerTickRate, + overflow_irq: 6, + enabled: 7, + } } /// Controls how often an enabled timer ticks upward. diff --git a/src/lib.rs b/src/lib.rs index c72a2cf..9361a12 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,7 +20,7 @@ //! **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. -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. /// diff --git a/src/oam.rs b/src/oam.rs index f9c0cef..958158b 100644 --- a/src/oam.rs +++ b/src/oam.rs @@ -15,17 +15,15 @@ newtype! { OBJAttr0, u16 } impl OBJAttr0 { - bool_bits!(u16, [(12, mosaic), (13, is_8bpp),]); - - multi_bits!( - u16, - [ - (0, 8, row_coordinate), - (8, 2, obj_rendering, ObjectRender, Normal, Affine, Disabled, DoubleAreaAffine), - (10, 2, obj_mode, ObjectMode, Normal, SemiTransparent, OBJWindow), - (14, 2, obj_shape, ObjectShape, Square, Horizontal, Vertical), - ] - ); + phantom_fields! { + self.0: u16, + row_coordinate: 0-7, + obj_rendering: 8-9=ObjectRender, + obj_mode: 10-11=ObjectMode, + mosaic: 12, + is_8bpp: 13, + obj_shape: 14-15=ObjectShape, + } } /// What style of rendering for this object @@ -81,16 +79,14 @@ newtype! { OBJAttr1, u16 } impl OBJAttr1 { - bool_bits!(u16, [(12, hflip), (13, vflip),]); - - multi_bits!( - u16, - [ - (0, 9, col_coordinate), - (9, 5, affine_index), - (14, 2, obj_size, ObjectSize, Zero, One, Two, Three), - ] - ); + phantom_fields! { + self.0: u16, + col_coordinate: 0-8, + affine_index: 9-13, + hflip: 12, + vflip: 13, + obj_size: 14-15=ObjectSize, + } } /// The object's size. @@ -127,5 +123,10 @@ newtype! { OBJAttr2, u16 } 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, + } } diff --git a/src/vram/text.rs b/src/vram/text.rs index bb433f5..44a07d0 100644 --- a/src/vram/text.rs +++ b/src/vram/text.rs @@ -9,13 +9,17 @@ newtype! { } impl TextScreenblockEntry { /// Generates a default entry with the specified tile index. - pub const fn from_tile_index(index: u16) -> Self { - Self::new().with_tile_index(index) + pub const fn from_tile_id(id: u16) -> Self { + Self::new().with_tile_id(id) } - bool_bits!(u16, [(10, hflip), (11, vflip)]); - - multi_bits!(u16, [(0, 10, tile_index), (12, 4, palbank)]); + phantom_fields! { + self.0: u16, + tile_id: 0-9, + hflip: 10, + vflip: 11, + palbank: 12-15, + } } newtype! { From 4c7ec468d02538b42999edfc582a246aee62acf5 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Sat, 29 Dec 2018 20:17:48 -0700 Subject: [PATCH 2/9] Modules and newtypes, joy! --- src/bios.rs | 1 - src/io/background.rs | 1 - src/io/display.rs | 4 --- src/io/dma.rs | 1 - src/io/keypad.rs | 2 -- src/io/timers.rs | 1 - src/lib.rs | 61 +++++++++++++++++++++++++++++++++++++++----- src/oam.rs | 3 --- src/rom.rs | 1 + src/sram.rs | 1 + src/vram/affine.rs | 1 - src/vram/text.rs | 1 - src/wram.rs | 1 + 13 files changed, 57 insertions(+), 22 deletions(-) create mode 100644 src/rom.rs create mode 100644 src/sram.rs create mode 100644 src/wram.rs diff --git a/src/bios.rs b/src/bios.rs index ce01862..175446f 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -104,7 +104,6 @@ pub unsafe fn register_ram_reset(flags: RegisterRAMResetFlags) { } newtype! { /// Flags for use with `register_ram_reset`. - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] RegisterRAMResetFlags, u8 } #[allow(missing_docs)] diff --git a/src/io/background.rs b/src/io/background.rs index c5df78b..493fb59 100644 --- a/src/io/background.rs +++ b/src/io/background.rs @@ -21,7 +21,6 @@ newtype! { /// Bit 8-12: Screen Base Block (0 through 31, 2k each) /// Bit 13: Display area overflow wraps (otherwise transparent, affine BG only) /// Bit 14-15: Screen Size - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] BackgroundControlSetting, u16 } impl BackgroundControlSetting { diff --git a/src/io/display.rs b/src/io/display.rs index b5e52ae..ded95a5 100644 --- a/src/io/display.rs +++ b/src/io/display.rs @@ -24,7 +24,6 @@ newtype!( /// * 13: Window 0 display /// * 14: Window 1 display /// * 15: Object window - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] DisplayControlSetting, u16 ); @@ -103,12 +102,10 @@ pub const DISPSTAT: VolAddress = unsafe { VolAddress::new_ newtype!( /// A newtype over display status and interrupt control values. - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] DisplayStatusSetting, u16 ); -#[allow(missing_docs)] impl DisplayStatusSetting { phantom_fields! { self.0: u16, @@ -168,7 +165,6 @@ newtype! { /// * Bits 4-7: BG mosaic vertical increase /// * Bits 8-11: Object mosaic horizontal increase /// * Bits 12-15: Object mosaic vertical increase - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] MosaicSetting, u16 } impl MosaicSetting { diff --git a/src/io/dma.rs b/src/io/dma.rs index 7dca8de..bea9669 100644 --- a/src/io/dma.rs +++ b/src/io/dma.rs @@ -63,7 +63,6 @@ use super::*; newtype! { /// Allows you to configure a DMA unit. - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] DMAControlSetting, u16 } #[allow(missing_docs)] diff --git a/src/io/keypad.rs b/src/io/keypad.rs index ec24995..bbbbf3a 100644 --- a/src/io/keypad.rs +++ b/src/io/keypad.rs @@ -27,7 +27,6 @@ newtype! { /// /// Methods here follow the "high-active" convention, where a bit is enabled /// when it's part of the set. - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] KeyInput, u16 } @@ -100,7 +99,6 @@ newtype! { /// NOTE: This _only_ configures the operation of when keypad interrupts can /// fire. You must still set the `IME` to have interrupts at all, and you must /// further set `IE` for keypad interrupts to be possible. - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] KeyInterruptSetting, u16 } #[allow(missing_docs)] diff --git a/src/io/timers.rs b/src/io/timers.rs index 6086ebe..25cc516 100644 --- a/src/io/timers.rs +++ b/src/io/timers.rs @@ -61,7 +61,6 @@ newtype! { /// mode naturally does nothing when used with Timer 0. /// * Bit 6: Raise a timer interrupt upon overflow. /// * Bit 7: Enable the timer. - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] TimerControlSetting, u16 } impl TimerControlSetting { diff --git a/src/lib.rs b/src/lib.rs index 9361a12..82b9286 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,22 +28,29 @@ pub(crate) use gba_proc_macro::phantom_fields; /// of your docs and derives in front of your newtype in the same way you would /// for a normal struct. Then the inner type to be wrapped it name. /// -/// The macro _assumes_ that you'll be using it to wrap zero safe numeric types, -/// so it automatically provides a `const fn` method for `new` that just wraps -/// `0`. If this is not desired you can add `, no frills` to the invocation. +/// The macro _assumes_ that you'll be using it to wrap numeric types and that +/// it's safe to have a `0` value, so it automatically provides a `const fn` +/// method for `new` that just wraps `0`. Also, it derives Debug, Clone, Copy, +/// Default, PartialEq, and Eq. If all this is not desired you can add `, no +/// frills` to the invocation. /// /// Example: /// ``` /// newtype! { /// /// Records a particular key press combination. -/// #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] /// KeyInput, u16 /// } +/// newtype! { +/// /// You can't derive most stuff above array size 32, so we add +/// /// the `, no frills` modifier. +/// BigArray, [u8; 200], no frills +/// } /// ``` #[macro_export] macro_rules! newtype { ($(#[$attr:meta])* $new_name:ident, $v:vis $old_name:ty) => { $(#[$attr])* + #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] #[repr(transparent)] pub struct $new_name($v $old_name); impl $new_name { @@ -60,18 +67,58 @@ macro_rules! newtype { }; } +#[macro_export] +macro_rules! newtype_enum { + ( + $(#[$struct_attr:meta])* + $new_name:ident = $old_name:ident, + $($(#[$tag_attr:meta])* $tag_name:ident = $base_value:expr,)* + ) => { + $(#[$struct_attr])* + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr($old_name)] + pub enum $new_name { + $( + $(#[$tag_attr])* + $tag_name = $base_value, + )* + } + }; +} + +newtype_enum! { + /// the Foo + Foo = u16, + /// the Bar + Bar = 0, + /// The Zap + Zap = 1, +} + pub mod base; pub(crate) use self::base::*; + pub mod bios; + +pub mod wram; + pub mod io; -pub mod mgba; -pub mod oam; + pub mod palram; + pub mod vram; +pub mod oam; + +pub mod rom; + +pub mod sram; + +pub mod mgba; + newtype! { /// A color on the GBA is an RGB 5.5.5 within a `u16` - #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + #[derive(PartialOrd, Ord, Hash)] Color, u16 } diff --git a/src/oam.rs b/src/oam.rs index 958158b..897e76e 100644 --- a/src/oam.rs +++ b/src/oam.rs @@ -11,7 +11,6 @@ newtype! { /// * Bit 12: Mosaic /// * Bit 13: is 8bpp /// * Bits 14-15: Object Shape: Square, Horizontal, Vertical - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] OBJAttr0, u16 } impl OBJAttr0 { @@ -75,7 +74,6 @@ newtype! { /// * Normal render: Bit 12 holds hflip and 13 holds vflip. /// * Affine render: The affine parameter selection. /// * Bits 14-15: Object Size - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] OBJAttr1, u16 } impl OBJAttr1 { @@ -119,7 +117,6 @@ newtype! { /// * Bits 0-9: Base Tile Index (tile offset from CBB4) /// * Bits 10-11: Priority /// * Bits 12-15: Palbank (if using 4bpp) - #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] OBJAttr2, u16 } impl OBJAttr2 { diff --git a/src/rom.rs b/src/rom.rs new file mode 100644 index 0000000..2414747 --- /dev/null +++ b/src/rom.rs @@ -0,0 +1 @@ +//! Module for things related to ROM. diff --git a/src/sram.rs b/src/sram.rs new file mode 100644 index 0000000..a294d5f --- /dev/null +++ b/src/sram.rs @@ -0,0 +1 @@ +//! Module for things related to SRAM. diff --git a/src/vram/affine.rs b/src/vram/affine.rs index 57293a0..6b1f556 100644 --- a/src/vram/affine.rs +++ b/src/vram/affine.rs @@ -4,7 +4,6 @@ use super::*; newtype! { /// A screenblock entry for use in Affine mode. - #[derive(Debug, Clone, Copy, Default)] AffineScreenblockEntry, u8 } diff --git a/src/vram/text.rs b/src/vram/text.rs index 44a07d0..07db59b 100644 --- a/src/vram/text.rs +++ b/src/vram/text.rs @@ -4,7 +4,6 @@ use super::*; newtype! { /// A screenblock entry for use in Text mode. - #[derive(Debug, Clone, Copy, Default)] TextScreenblockEntry, u16 } impl TextScreenblockEntry { diff --git a/src/wram.rs b/src/wram.rs new file mode 100644 index 0000000..405d022 --- /dev/null +++ b/src/wram.rs @@ -0,0 +1 @@ +//! Module for things related to WRAM. From 09b4c8804cd50a63679c0da7d10266cbfa37660d Mon Sep 17 00:00:00 2001 From: Lokathor Date: Sat, 29 Dec 2018 20:18:09 -0700 Subject: [PATCH 3/9] YABU: Yet Another Book Update --- README.md | 14 +- .../00-concepts-index.md} | 0 .../00-introduction-index.md} | 0 .../00-non-video-index.md} | 0 .../00-quirks-index.md} | 0 .../00-index.md => src-bak/00-video-index.md} | 0 .../04-non-video => src-bak}/01-buttons.md | 0 book/{src/02-concepts => src-bak}/01-cpu.md | 0 book/{src/01-quirks => src-bak}/01-no_std.md | 0 .../01-requirements.md | 0 book/{src/03-video => src-bak}/01-rgb15.md | 0 book/{src/02-concepts => src-bak}/02-bios.md | 0 .../01-quirks => src-bak}/02-fixed_only.md | 0 .../02-goals_and_style.md | 0 .../04-non-video => src-bak}/02-timers.md | 0 book/{src/04-non-video => src-bak}/03-dma.md | 0 .../03-volatile_destination.md | 0 book/{src/02-concepts => src-bak}/03-wram.md | 0 .../04-io-registers.md | 0 book/{src/01-quirks => src-bak}/04-newtype.md | 0 .../{src/04-non-video => src-bak}/04-sound.md | 0 .../01-quirks => src-bak}/05-const_asserts.md | 0 .../05-help_and_resources.md | 0 .../04-non-video => src-bak}/05-interrupts.md | 0 .../{src/02-concepts => src-bak}/05-palram.md | 0 .../04-non-video => src-bak}/06-link_cable.md | 0 book/{src/02-concepts => src-bak}/06-vram.md | 0 .../04-non-video => src-bak}/07-game_pak.md | 0 book/{src/02-concepts => src-bak}/07-oam.md | 0 book/{src/02-concepts => src-bak}/08-rom.md | 0 book/{src/02-concepts => src-bak}/09-sram.md | 0 book/src-bak/{ch03 => }/gba_prng.md | 0 book/src-bak/{ch03 => }/index.md | 0 book/src-bak/{ch01 => }/io_registers.md | 0 book/src-bak/{ch02 => }/light_cycle.md | 0 book/src-bak/{ch03 => }/memory_game.md | 0 book/src-bak/{ch03 => }/obj_memory_2d1d.jpg | Bin .../src-bak/{ch03 => }/regular_backgrounds.md | 0 book/src-bak/{ch03 => }/regular_objects.md | 0 .../{ch03 => }/screenshot_checkers.png | Bin .../the_display_control_register.md | 0 .../{ch02 => }/the_key_input_register.md | 0 .../src-bak/{ch02 => }/the_vcount_register.md | 0 book/src-bak/{ch03 => }/tile_data.md | 0 book/src-bak/{ch01 => }/video_memory_intro.md | 0 book/src/00-introduction/04-hello-magic.md | 52 --- book/src/03-video/TODO.md | 1 - book/src/05-examples/00-index.md | 1 - book/src/SUMMARY.md | 36 +- ...elopment-setup.md => development-setup.md} | 39 ++ book/src/gba-asm.md | 106 +++++ docs/00-introduction/00-index.html | 202 --------- docs/00-introduction/01-requirements.html | 224 ---------- docs/00-introduction/02-goals_and_style.html | 225 ---------- docs/00-introduction/04-hello-magic.html | 242 ----------- docs/00-introduction/05-newtype.html | 313 -------------- .../06-help_and_resources.html | 255 ------------ docs/01-limitations/00-index.html | 200 --------- docs/01-limitations/01-no_floats.html | 200 --------- docs/01-limitations/02-core_only.html | 200 --------- .../03-volatile_destination.html | 200 --------- docs/02-concepts/00-index.html | 200 --------- docs/02-concepts/01-cpu.html | 200 --------- docs/02-concepts/02-bios.html | 200 --------- docs/02-concepts/03-wram.html | 200 --------- docs/02-concepts/04-io-registers.html | 200 --------- docs/02-concepts/05-palram.html | 200 --------- docs/02-concepts/06-vram.html | 200 --------- docs/02-concepts/07-oam.html | 200 --------- docs/02-concepts/08-rom.html | 200 --------- docs/02-concepts/09-sram.html | 200 --------- docs/03-video/00-index.html | 200 --------- docs/03-video/01-rgb15.html | 200 --------- docs/03-video/TODO.html | 200 --------- docs/04-non-video/00-index.html | 200 --------- docs/04-non-video/01-buttons.html | 200 --------- docs/04-non-video/02-timers.html | 200 --------- docs/04-non-video/03-dma.html | 200 --------- docs/04-non-video/04-sound.html | 200 --------- docs/04-non-video/05-interrupts.html | 200 --------- docs/04-non-video/06-network.html | 200 --------- docs/04-non-video/07-game_pak.html | 200 --------- docs/05-examples/00-index.html | 200 --------- docs/05-examples/01-hello_magic.html | 200 --------- docs/05-examples/02-hello_world.html | 200 --------- docs/05-examples/03-light_cycle.html | 200 --------- docs/05-examples/04-bg_demo.html | 192 --------- ...ment-setup.html => development-setup.html} | 80 ++-- docs/gba-asm.html | 293 +++++++++++++ docs/index.html | 197 ++++++++- docs/print.html | 387 +++++------------- docs/searchindex.js | 2 +- docs/searchindex.json | 2 +- 93 files changed, 794 insertions(+), 7869 deletions(-) rename book/{src/02-concepts/00-index.md => src-bak/00-concepts-index.md} (100%) rename book/{src/00-introduction/00-index.md => src-bak/00-introduction-index.md} (100%) rename book/{src/04-non-video/00-index.md => src-bak/00-non-video-index.md} (100%) rename book/{src/01-quirks/00-index.md => src-bak/00-quirks-index.md} (100%) rename book/{src/03-video/00-index.md => src-bak/00-video-index.md} (100%) rename book/{src/04-non-video => src-bak}/01-buttons.md (100%) rename book/{src/02-concepts => src-bak}/01-cpu.md (100%) rename book/{src/01-quirks => src-bak}/01-no_std.md (100%) rename book/{src/00-introduction => src-bak}/01-requirements.md (100%) rename book/{src/03-video => src-bak}/01-rgb15.md (100%) rename book/{src/02-concepts => src-bak}/02-bios.md (100%) rename book/{src/01-quirks => src-bak}/02-fixed_only.md (100%) rename book/{src/00-introduction => src-bak}/02-goals_and_style.md (100%) rename book/{src/04-non-video => src-bak}/02-timers.md (100%) rename book/{src/04-non-video => src-bak}/03-dma.md (100%) rename book/{src/01-quirks => src-bak}/03-volatile_destination.md (100%) rename book/{src/02-concepts => src-bak}/03-wram.md (100%) rename book/{src/02-concepts => src-bak}/04-io-registers.md (100%) rename book/{src/01-quirks => src-bak}/04-newtype.md (100%) rename book/{src/04-non-video => src-bak}/04-sound.md (100%) rename book/{src/01-quirks => src-bak}/05-const_asserts.md (100%) rename book/{src/00-introduction => src-bak}/05-help_and_resources.md (100%) rename book/{src/04-non-video => src-bak}/05-interrupts.md (100%) rename book/{src/02-concepts => src-bak}/05-palram.md (100%) rename book/{src/04-non-video => src-bak}/06-link_cable.md (100%) rename book/{src/02-concepts => src-bak}/06-vram.md (100%) rename book/{src/04-non-video => src-bak}/07-game_pak.md (100%) rename book/{src/02-concepts => src-bak}/07-oam.md (100%) rename book/{src/02-concepts => src-bak}/08-rom.md (100%) rename book/{src/02-concepts => src-bak}/09-sram.md (100%) rename book/src-bak/{ch03 => }/gba_prng.md (100%) rename book/src-bak/{ch03 => }/index.md (100%) rename book/src-bak/{ch01 => }/io_registers.md (100%) rename book/src-bak/{ch02 => }/light_cycle.md (100%) rename book/src-bak/{ch03 => }/memory_game.md (100%) rename book/src-bak/{ch03 => }/obj_memory_2d1d.jpg (100%) rename book/src-bak/{ch03 => }/regular_backgrounds.md (100%) rename book/src-bak/{ch03 => }/regular_objects.md (100%) rename book/src-bak/{ch03 => }/screenshot_checkers.png (100%) rename book/src-bak/{ch01 => }/the_display_control_register.md (100%) rename book/src-bak/{ch02 => }/the_key_input_register.md (100%) rename book/src-bak/{ch02 => }/the_vcount_register.md (100%) rename book/src-bak/{ch03 => }/tile_data.md (100%) rename book/src-bak/{ch01 => }/video_memory_intro.md (100%) delete mode 100644 book/src/00-introduction/04-hello-magic.md delete mode 100644 book/src/03-video/TODO.md delete mode 100644 book/src/05-examples/00-index.md rename book/src/{00-introduction/03-development-setup.md => development-setup.md} (86%) create mode 100644 book/src/gba-asm.md delete mode 100644 docs/00-introduction/00-index.html delete mode 100644 docs/00-introduction/01-requirements.html delete mode 100644 docs/00-introduction/02-goals_and_style.html delete mode 100644 docs/00-introduction/04-hello-magic.html delete mode 100644 docs/00-introduction/05-newtype.html delete mode 100644 docs/00-introduction/06-help_and_resources.html delete mode 100644 docs/01-limitations/00-index.html delete mode 100644 docs/01-limitations/01-no_floats.html delete mode 100644 docs/01-limitations/02-core_only.html delete mode 100644 docs/01-limitations/03-volatile_destination.html delete mode 100644 docs/02-concepts/00-index.html delete mode 100644 docs/02-concepts/01-cpu.html delete mode 100644 docs/02-concepts/02-bios.html delete mode 100644 docs/02-concepts/03-wram.html delete mode 100644 docs/02-concepts/04-io-registers.html delete mode 100644 docs/02-concepts/05-palram.html delete mode 100644 docs/02-concepts/06-vram.html delete mode 100644 docs/02-concepts/07-oam.html delete mode 100644 docs/02-concepts/08-rom.html delete mode 100644 docs/02-concepts/09-sram.html delete mode 100644 docs/03-video/00-index.html delete mode 100644 docs/03-video/01-rgb15.html delete mode 100644 docs/03-video/TODO.html delete mode 100644 docs/04-non-video/00-index.html delete mode 100644 docs/04-non-video/01-buttons.html delete mode 100644 docs/04-non-video/02-timers.html delete mode 100644 docs/04-non-video/03-dma.html delete mode 100644 docs/04-non-video/04-sound.html delete mode 100644 docs/04-non-video/05-interrupts.html delete mode 100644 docs/04-non-video/06-network.html delete mode 100644 docs/04-non-video/07-game_pak.html delete mode 100644 docs/05-examples/00-index.html delete mode 100644 docs/05-examples/01-hello_magic.html delete mode 100644 docs/05-examples/02-hello_world.html delete mode 100644 docs/05-examples/03-light_cycle.html delete mode 100644 docs/05-examples/04-bg_demo.html rename docs/{00-introduction/03-development-setup.html => development-setup.html} (72%) create mode 100644 docs/gba-asm.html diff --git a/README.md b/README.md index 0233d8f..a8a30da 100644 --- a/README.md +++ b/README.md @@ -8,16 +8,18 @@ # gba -This repository is both a [Tutorial Book](https://rust-console.github.io/gba/) -that teaches you what you need to know to write Rust games for the GameBoy -Advance (GBA), and also a [crate](https://crates.io/crates/gba) that you can -use to do the same. +_Eventually_ there will be a full [Tutorial +Book](https://rust-console.github.io/gba/) that goes along with this crate. +However, currently the development focus is leaning towards having minimal +coverage of all the parts of the GBA. Until that's done, unfortunately the book +will be in a rather messy state. ## First Time Setup Writing a Rust program for the GBA requires a fair amount of special setup. All -of the steps are detailed for you [in the Introduction chapter of the -book](https://rust-console.github.io/gba/00-introduction/03-development-setup.html). +of the steps are detailed for you in the [Development +Setup](https://rust-console.github.io/gba/development-setup.html) part at the +start of the book. If you've done the described global setup once before and just want to get a new project started quickly we got you covered: diff --git a/book/src/02-concepts/00-index.md b/book/src-bak/00-concepts-index.md similarity index 100% rename from book/src/02-concepts/00-index.md rename to book/src-bak/00-concepts-index.md diff --git a/book/src/00-introduction/00-index.md b/book/src-bak/00-introduction-index.md similarity index 100% rename from book/src/00-introduction/00-index.md rename to book/src-bak/00-introduction-index.md diff --git a/book/src/04-non-video/00-index.md b/book/src-bak/00-non-video-index.md similarity index 100% rename from book/src/04-non-video/00-index.md rename to book/src-bak/00-non-video-index.md diff --git a/book/src/01-quirks/00-index.md b/book/src-bak/00-quirks-index.md similarity index 100% rename from book/src/01-quirks/00-index.md rename to book/src-bak/00-quirks-index.md diff --git a/book/src/03-video/00-index.md b/book/src-bak/00-video-index.md similarity index 100% rename from book/src/03-video/00-index.md rename to book/src-bak/00-video-index.md diff --git a/book/src/04-non-video/01-buttons.md b/book/src-bak/01-buttons.md similarity index 100% rename from book/src/04-non-video/01-buttons.md rename to book/src-bak/01-buttons.md diff --git a/book/src/02-concepts/01-cpu.md b/book/src-bak/01-cpu.md similarity index 100% rename from book/src/02-concepts/01-cpu.md rename to book/src-bak/01-cpu.md diff --git a/book/src/01-quirks/01-no_std.md b/book/src-bak/01-no_std.md similarity index 100% rename from book/src/01-quirks/01-no_std.md rename to book/src-bak/01-no_std.md diff --git a/book/src/00-introduction/01-requirements.md b/book/src-bak/01-requirements.md similarity index 100% rename from book/src/00-introduction/01-requirements.md rename to book/src-bak/01-requirements.md diff --git a/book/src/03-video/01-rgb15.md b/book/src-bak/01-rgb15.md similarity index 100% rename from book/src/03-video/01-rgb15.md rename to book/src-bak/01-rgb15.md diff --git a/book/src/02-concepts/02-bios.md b/book/src-bak/02-bios.md similarity index 100% rename from book/src/02-concepts/02-bios.md rename to book/src-bak/02-bios.md diff --git a/book/src/01-quirks/02-fixed_only.md b/book/src-bak/02-fixed_only.md similarity index 100% rename from book/src/01-quirks/02-fixed_only.md rename to book/src-bak/02-fixed_only.md diff --git a/book/src/00-introduction/02-goals_and_style.md b/book/src-bak/02-goals_and_style.md similarity index 100% rename from book/src/00-introduction/02-goals_and_style.md rename to book/src-bak/02-goals_and_style.md diff --git a/book/src/04-non-video/02-timers.md b/book/src-bak/02-timers.md similarity index 100% rename from book/src/04-non-video/02-timers.md rename to book/src-bak/02-timers.md diff --git a/book/src/04-non-video/03-dma.md b/book/src-bak/03-dma.md similarity index 100% rename from book/src/04-non-video/03-dma.md rename to book/src-bak/03-dma.md diff --git a/book/src/01-quirks/03-volatile_destination.md b/book/src-bak/03-volatile_destination.md similarity index 100% rename from book/src/01-quirks/03-volatile_destination.md rename to book/src-bak/03-volatile_destination.md diff --git a/book/src/02-concepts/03-wram.md b/book/src-bak/03-wram.md similarity index 100% rename from book/src/02-concepts/03-wram.md rename to book/src-bak/03-wram.md diff --git a/book/src/02-concepts/04-io-registers.md b/book/src-bak/04-io-registers.md similarity index 100% rename from book/src/02-concepts/04-io-registers.md rename to book/src-bak/04-io-registers.md diff --git a/book/src/01-quirks/04-newtype.md b/book/src-bak/04-newtype.md similarity index 100% rename from book/src/01-quirks/04-newtype.md rename to book/src-bak/04-newtype.md diff --git a/book/src/04-non-video/04-sound.md b/book/src-bak/04-sound.md similarity index 100% rename from book/src/04-non-video/04-sound.md rename to book/src-bak/04-sound.md diff --git a/book/src/01-quirks/05-const_asserts.md b/book/src-bak/05-const_asserts.md similarity index 100% rename from book/src/01-quirks/05-const_asserts.md rename to book/src-bak/05-const_asserts.md diff --git a/book/src/00-introduction/05-help_and_resources.md b/book/src-bak/05-help_and_resources.md similarity index 100% rename from book/src/00-introduction/05-help_and_resources.md rename to book/src-bak/05-help_and_resources.md diff --git a/book/src/04-non-video/05-interrupts.md b/book/src-bak/05-interrupts.md similarity index 100% rename from book/src/04-non-video/05-interrupts.md rename to book/src-bak/05-interrupts.md diff --git a/book/src/02-concepts/05-palram.md b/book/src-bak/05-palram.md similarity index 100% rename from book/src/02-concepts/05-palram.md rename to book/src-bak/05-palram.md diff --git a/book/src/04-non-video/06-link_cable.md b/book/src-bak/06-link_cable.md similarity index 100% rename from book/src/04-non-video/06-link_cable.md rename to book/src-bak/06-link_cable.md diff --git a/book/src/02-concepts/06-vram.md b/book/src-bak/06-vram.md similarity index 100% rename from book/src/02-concepts/06-vram.md rename to book/src-bak/06-vram.md diff --git a/book/src/04-non-video/07-game_pak.md b/book/src-bak/07-game_pak.md similarity index 100% rename from book/src/04-non-video/07-game_pak.md rename to book/src-bak/07-game_pak.md diff --git a/book/src/02-concepts/07-oam.md b/book/src-bak/07-oam.md similarity index 100% rename from book/src/02-concepts/07-oam.md rename to book/src-bak/07-oam.md diff --git a/book/src/02-concepts/08-rom.md b/book/src-bak/08-rom.md similarity index 100% rename from book/src/02-concepts/08-rom.md rename to book/src-bak/08-rom.md diff --git a/book/src/02-concepts/09-sram.md b/book/src-bak/09-sram.md similarity index 100% rename from book/src/02-concepts/09-sram.md rename to book/src-bak/09-sram.md diff --git a/book/src-bak/ch03/gba_prng.md b/book/src-bak/gba_prng.md similarity index 100% rename from book/src-bak/ch03/gba_prng.md rename to book/src-bak/gba_prng.md diff --git a/book/src-bak/ch03/index.md b/book/src-bak/index.md similarity index 100% rename from book/src-bak/ch03/index.md rename to book/src-bak/index.md diff --git a/book/src-bak/ch01/io_registers.md b/book/src-bak/io_registers.md similarity index 100% rename from book/src-bak/ch01/io_registers.md rename to book/src-bak/io_registers.md diff --git a/book/src-bak/ch02/light_cycle.md b/book/src-bak/light_cycle.md similarity index 100% rename from book/src-bak/ch02/light_cycle.md rename to book/src-bak/light_cycle.md diff --git a/book/src-bak/ch03/memory_game.md b/book/src-bak/memory_game.md similarity index 100% rename from book/src-bak/ch03/memory_game.md rename to book/src-bak/memory_game.md diff --git a/book/src-bak/ch03/obj_memory_2d1d.jpg b/book/src-bak/obj_memory_2d1d.jpg similarity index 100% rename from book/src-bak/ch03/obj_memory_2d1d.jpg rename to book/src-bak/obj_memory_2d1d.jpg diff --git a/book/src-bak/ch03/regular_backgrounds.md b/book/src-bak/regular_backgrounds.md similarity index 100% rename from book/src-bak/ch03/regular_backgrounds.md rename to book/src-bak/regular_backgrounds.md diff --git a/book/src-bak/ch03/regular_objects.md b/book/src-bak/regular_objects.md similarity index 100% rename from book/src-bak/ch03/regular_objects.md rename to book/src-bak/regular_objects.md diff --git a/book/src-bak/ch03/screenshot_checkers.png b/book/src-bak/screenshot_checkers.png similarity index 100% rename from book/src-bak/ch03/screenshot_checkers.png rename to book/src-bak/screenshot_checkers.png diff --git a/book/src-bak/ch01/the_display_control_register.md b/book/src-bak/the_display_control_register.md similarity index 100% rename from book/src-bak/ch01/the_display_control_register.md rename to book/src-bak/the_display_control_register.md diff --git a/book/src-bak/ch02/the_key_input_register.md b/book/src-bak/the_key_input_register.md similarity index 100% rename from book/src-bak/ch02/the_key_input_register.md rename to book/src-bak/the_key_input_register.md diff --git a/book/src-bak/ch02/the_vcount_register.md b/book/src-bak/the_vcount_register.md similarity index 100% rename from book/src-bak/ch02/the_vcount_register.md rename to book/src-bak/the_vcount_register.md diff --git a/book/src-bak/ch03/tile_data.md b/book/src-bak/tile_data.md similarity index 100% rename from book/src-bak/ch03/tile_data.md rename to book/src-bak/tile_data.md diff --git a/book/src-bak/ch01/video_memory_intro.md b/book/src-bak/video_memory_intro.md similarity index 100% rename from book/src-bak/ch01/video_memory_intro.md rename to book/src-bak/video_memory_intro.md diff --git a/book/src/00-introduction/04-hello-magic.md b/book/src/00-introduction/04-hello-magic.md deleted file mode 100644 index 5d8a679..0000000 --- a/book/src/00-introduction/04-hello-magic.md +++ /dev/null @@ -1,52 +0,0 @@ -# Hello, Magic - -So we know all the steps to build our source, we just need some source. - -We're beginners, so we'll start small. With normal programming there's usually a -console available, so the minimal program prints "Hello, world" to the terminal. -On a GBA we don't have a terminal and standard out and all that, so the minimal -program draws a red, blue, and green dot to the screen. - -At the lowest level of device programming, it's all [Magic -Numbers](https://en.wikipedia.org/wiki/Magic_number_(programming)). You write -special values to special places and then the hardware does something. A clear -API makes every magic number and magic location easy to understand. A clear _and -good_ API also prevents you from using the wrong magic number in the wrong place -and causing problems for yourself. - -This is the minimal example to just test that our build system is all set, so -just this once we'll go _full_ magic number crazy town, for fun. Ready? Here -goes: - -`hello_magic.rs`: - -```rust -#![no_std] -#![feature(start)] - -#[panic_handler] -fn panic(_info: &core::panic::PanicInfo) -> ! { - loop {} -} - -#[start] -fn main(_argc: isize, _argv: *const *const u8) -> isize { - unsafe { - (0x400_0000 as *mut u16).write_volatile(0x0403); - (0x600_0000 as *mut u16).offset(120 + 80 * 240).write_volatile(0x001F); - (0x600_0000 as *mut u16).offset(136 + 80 * 240).write_volatile(0x03E0); - (0x600_0000 as *mut u16).offset(120 + 96 * 240).write_volatile(0x7C00); - loop {} - } -} -``` - -Throw that into your project skeleton, build the program, and give it a run. You -should see a red, green, and blue dot close-ish to the middle of the screen. If -you don't, something _already_ went wrong. Double check things, phone a friend, -write your senators, try asking `Lokathor` or `Ketsuban` on the [Rust Community -Discord](https://discordapp.com/invite/aVESxV8), until you're eventually able to -get your three dots going. - -Of course, I'm sure you want to know why those numbers are the numbers to use. -Well that's what the whole rest of the book is about! diff --git a/book/src/03-video/TODO.md b/book/src/03-video/TODO.md deleted file mode 100644 index 4640904..0000000 --- a/book/src/03-video/TODO.md +++ /dev/null @@ -1 +0,0 @@ -# TODO diff --git a/book/src/05-examples/00-index.md b/book/src/05-examples/00-index.md deleted file mode 100644 index df635b4..0000000 --- a/book/src/05-examples/00-index.md +++ /dev/null @@ -1 +0,0 @@ -# Examples diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index a697feb..153ef29 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -1,37 +1,5 @@ # Rust GBA Guide -* [Introduction](00-introduction/00-index.md) - * [Reader Requirements](00-introduction/01-requirements.md) - * [Book Goals and Style](00-introduction/02-goals_and_style.md) - * [Development Setup](00-introduction/03-development-setup.md) - * [Hello, Magic](00-introduction/04-hello-magic.md) - * [Help and Resources](00-introduction/05-help_and_resources.md) -* [Quirks](01-quirks/00-index.md) - * [No Std](01-quirks/01-no_std.md) - * [Fixed Only](01-quirks/02-fixed_only.md) - * [Volatile Destination](01-quirks/03-volatile_destination.md) - * [Newtype](01-quirks/04-newtype.md) - * [Const Asserts](01-quirks/05-const_asserts.md) -* [Concepts](02-concepts/00-index.md) - * [CPU](02-concepts/01-cpu.md) - * [BIOS](02-concepts/02-bios.md) - * [Work RAM](02-concepts/03-wram.md) - * [IO Registers](02-concepts/04-io-registers.md) - * [Palette RAM](02-concepts/05-palram.md) - * [Video RAM](02-concepts/06-vram.md) - * [Object Attribute Memory](02-concepts/07-oam.md) - * [Game Pak ROM / Flash ROM](02-concepts/08-rom.md) - * [Save RAM](02-concepts/09-sram.md) -* [Video](03-video/00-index.md) - * [RBG15 Color](03-video/01-rgb15.md) - * [TODO](03-video/TODO.md) -* [Non-Video](04-non-video/00-index.md) - * [Buttons](04-non-video/01-buttons.md) - * [Timers](04-non-video/02-timers.md) - * [Direct Memory Access](04-non-video/03-dma.md) - * [Sound](04-non-video/04-sound.md) - * [Interrupts](04-non-video/05-interrupts.md) - * [Link Cable](04-non-video/06-link_cable.md) - * [Game Pak](04-non-video/07-game_pak.md) -* [Examples](05-examples/00-index.md) +* [Development Setup](development-setup.md) +* [GBA Assembly](gba-asm.md) diff --git a/book/src/00-introduction/03-development-setup.md b/book/src/development-setup.md similarity index 86% rename from book/src/00-introduction/03-development-setup.md rename to book/src/development-setup.md index 26c80f0..f84c387 100644 --- a/book/src/00-introduction/03-development-setup.md +++ b/book/src/development-setup.md @@ -141,3 +141,42 @@ And you're _finally_ done! Of course, you probably want to make a script for all that, but it's up to you. On our own project we have it mostly set up within a `Makefile.toml` which runs using the [cargo-make](https://github.com/sagiegurari/cargo-make) plugin. + +## Checking Your Setup + +As I said, you need some source code to compile just to check that your +compilation pipeline is working. Here's a sample file that just puts three dots +on the screen without depending on any crates or anything at all. + +`hello_magic.rs`: + +```rust +#![no_std] +#![feature(start)] + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[start] +fn main(_argc: isize, _argv: *const *const u8) -> isize { + unsafe { + (0x400_0000 as *mut u16).write_volatile(0x0403); + (0x600_0000 as *mut u16).offset(120 + 80 * 240).write_volatile(0x001F); + (0x600_0000 as *mut u16).offset(136 + 80 * 240).write_volatile(0x03E0); + (0x600_0000 as *mut u16).offset(120 + 96 * 240).write_volatile(0x7C00); + loop {} + } +} +``` + +Throw that into your project skeleton, build the program, and give it a run. You +should see a red, green, and blue dot close-ish to the middle of the screen. If +you don't, something _already_ went wrong. Double check things, phone a friend, +write your senators, try asking `Lokathor` or `Ketsuban` on the [Rust Community +Discord](https://discordapp.com/invite/aVESxV8), until you're eventually able to +get your three dots going. + +Of course, I'm sure you want to know why those numbers are the numbers to use. +Well that's what the whole rest of the book is about! diff --git a/book/src/gba-asm.md b/book/src/gba-asm.md new file mode 100644 index 0000000..87f5e55 --- /dev/null +++ b/book/src/gba-asm.md @@ -0,0 +1,106 @@ +# GBA Assembly + +On the GBA sometimes you just end up using assembly. Not a whole lot, but +sometimes. Accordingly, you should know how assembly works on the GBA. + +* The [ARM Infocenter: + ARM7TDMI](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0210c/index.html) + is the basic authority for reference information. The GBA has a CPU with the + `ARMv4` ISA, the `ARMv4T` variant, and specifically the `ARM7TDMI` + microarchitecture. Someone at ARM decided that having both `ARM#` and `ARMv#` + was a good way to [version things](https://en.wikichip.org/wiki/arm/versions), + even when the numbers don't match, and the rest of us have been sad ever + since. The link there will take you to the correct book within the big pile of + ARM books available within the ARM Infocenter. Note that there is also a [PDF + Version](http://infocenter.arm.com/help/topic/com.arm.doc.ddi0210c/DDI0210B.pdf) + of the documentation available, if you'd like that. + +* The [GBATek: ARM CPU + Overview](https://problemkaputt.de/gbatek.htm#armcpuoverview) also has quite a + bit of info. Most of it is somewhat a duplication of what you'd find in the + ARM Infocenter reference manual, but it's also somewhat specialized towards + the GBA's specifics. It's in the usual, uh, "sparse" style that GBATEK is + written in, so I wouldn't suggest that read it first. + +* The [Compiler Explorer](https://rust.godbolt.org/z/ndCnk3) can be used to + quickly look at assembly output of your Rust code. That link there will load + up an essentially blank `no_std` file with `opt-level=3` set and targeting + `thumbv6m-none-eabi`. That's _not_ the same as the GBA (it's two ISA revisions + later, ARMv6 instead of ARMv4), but it's the closest CPU target that ships + with rustc, so it's the closest you can get with the compiler explorer + website. If you're very dedicated I suppose you could setup a [local + instance](https://github.com/mattgodbolt/compiler-explorer#running-a-local-instance) + of compiler explorer and then add the extra target definition and so on, but + that's _probably_ overkill. + +## ARM and THUMB + +The "T" part in `ARMv4T` and `ARM7TDMI` means "Thumb". An ARM chip that supports +Thumb mode has two different instruction sets instead of just one. The chip can +run in ARM mode with 32-bit instructions, or it can run in THUMB mode with +16-bit instructions. Apparently these modes are sometimes called `a32` and `t32` +in a more modern context, but I will stick with ARM and THUMB because that's +what other GBA references use (particularly GBATEK), and it's probably best to +be more in agreement with them than with stuff for Raspberry Pi programming or +whatever other modern ARM thing. + +On the GBA, the memory bus that physically transfers data from the game pak into +the device is a 16-bit memory bus. This means that if you need to transfer more +than 16 bits at a time you have to do more than one transfer. Since we'd like +our instructions to get to the CPU as fast as possible, we compile the majority +of our program with the THUMB instruction set. The ARM reference says that with +THUMB instructions on a 16-bit memory bus system you get about 160% performance +compared to using ARM instructions. That's absolutely something we want to take +advantage of. Also, your THUMB compiled code is about 65% of the same code +compiled with ARM. Since a game ROM can only be 32MB total, and we're trying to +fit in images and sound too, we want to get space savings where we can. + +You may wonder, why is the THUMB code 65% as large if the instructions +themselves are 50% as large, and why have ARM mode at all if there's such a +benefit to be had with THUMB? Well, THUMB mode doesn't support as many different +instructions as ARM mode does. Some lines of source code that can compile to a +single ARM instruction might need to compile into more than one THUMB +instruction. THUMB still has most of the really good instructions available, so +it all averages out to about 65%. + +That said, some parts of a GBA program _must_ be written in ARM mode. Also, ARM +mode does allow that increased instruction flexibility. So we _need_ to use ARM +some of the time, and we might just _want_ to use ARM even when we don't need +to. It is possible to switch modes on the fly, there's extremely minimal +overhead, even less than doing some function calls. The only problem is the +16-bit memory bus of the game pak giving us a needless speed penalty with our +ARM code. The CPU _executes_ the ARM instructions at full speed, but then it has +to wait while more instructions get sent in. What do we do? Well, code is +ultimately just a different kind of data. We can copy parts of our code off the +game pak ROM and place it into a part of the RAM that has a 32-bit memory bus. +Then the CPU can execute the code from there, going at full speed. Of course, +there's only a very small amount of RAM compared to the size of a game pak, so +we'll only do this with a few select functions. Exactly which functions will +probably depend on your game. + +One problem with this process is that Rust doesn't currently offer a way to mark +individual functions for being ARM or THUMB. The whole program is compiled in a +single mode. That's not an automatic killer, since we can use the `asm!` macro +to write some inline assembly, then within our inline assembly we switch from +THUMB to ARM, do some ARM stuff, and switch back to THUMB mode before the inline +assembly is over. Rust is none the wiser to what happened. Yeah, it's clunky, +that's why [it's on the 2019 +wishlist](https://github.com/rust-embedded/wg/issues/256#issuecomment-439677804) +to fix it (then LLVM can manage it automatically for you). + +The bigger problem is that when we do that all of our functions still start off +in THUMB mode, even if they temporarily use ARM mode. For the few bits of code +that must start _already in_ ARM mode, we're stuck. Those parts have to be +written in external assembly files and then included with the linker. We were +already going to write some assembly, and we already use more than one file in +our project all the time, those parts aren't a big problem. The big problem is +that using custom linker scripts isn't transitive between crates. + +What I mean is that once we have a file full of custom assembly that we're +linking in by hand, that's not "part of" the crate any more. At least not as +`cargo` see it. So we can't just upload it to `crates.io` and then depend on it +in other projects and have `cargo` download the right version and and include it +all automatically. We're back to fully manually copying files from the old +project into the new one, adding more lines to the linker script each time we +split up a new assembly file, all that stuff. Like the stone age. Sometimes ya +gotta suffer for your art. diff --git a/docs/00-introduction/00-index.html b/docs/00-introduction/00-index.html deleted file mode 100644 index ca89eb4..0000000 --- a/docs/00-introduction/00-index.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - Introduction - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Introduction

-

This is the book for learning how to write GBA games in Rust.

-

I'm Lokathor, the main author of the book. There's also Ketsuban who -provides the technical advisement, reviews the PRs, and keeps my crazy in check.

-

The book is a work in progress, as you can see if you actually try to open many -of the pages listed in the Table Of Contents.

-

Feedback

-

It's also often hard to tell when you've explained something properly to someone -who doesn't understand the concept yet. Please, if things don't make sense then -file an issue about it so I know -where things need to improve.

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/00-introduction/01-requirements.html b/docs/00-introduction/01-requirements.html deleted file mode 100644 index 1a77f27..0000000 --- a/docs/00-introduction/01-requirements.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - Reader Requirements - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Reader Requirements

-

This book naturally assumes that you've already read Rust's core book:

- -

Now, I know it sounds silly to say "if you wanna program Rust on this old -video game system you should already know how to program Rust", but the more -people I meet and chat with the more they tell me that they jumped into Rust -without reading any or all of the book. You know who you are.

-

Please, read the whole book!

-

In addition to the core book, there's also an expansion book that I will declare -to be required reading for this:

- -

The Rustonomicon is all about trying to demystify unsafe. We'll end up using a -fair bit of unsafe code as a natural consequence of doing direct hardware -manipulations. Using unsafe is like swinging a -sword, -you should start slowly, practice carefully, and always pay attention no matter -how experienced you think you've become.

-

That said, it's sometimes a necessary -tool to get the job done, so you -have to break out of the borderline pathological fear of using it that most rust -programmers tend to have.

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/00-introduction/02-goals_and_style.html b/docs/00-introduction/02-goals_and_style.html deleted file mode 100644 index 6644fdc..0000000 --- a/docs/00-introduction/02-goals_and_style.html +++ /dev/null @@ -1,225 +0,0 @@ - - - - - - Book Goals and Style - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Book Goals and Style

-

So, what's this book actually gonna teach you?

-

I'm not gonna tell you how to use a crate that already exists.

-

Don't get me wrong, there is a gba crate, and -it's on crates.io and all that jazz.

-

However, unlike most crates that come with a tutorial book, I don't want to just -teach you how to use the crate. What I want is to teach you what you need to -know so that you could build the crate yourself, from scratch, if it didn't -already exist for you. Let's call it the Handmade -Hero school of design. Much more than you might find -in other Rust crate books, I'll be attempting to show a lot of the why in -addition to just the how. Once you know how to do it all on your own, you can -decide for yourself if the gba crate does it well, or if you think you can -come up with something that suits your needs better.

-

Overall the book is sorted for easy review once you're trying to program -something, and the GBA has a few interconnected concepts, so some parts of the -book end up having to refer you to portions that you haven't read yet. The -chapters and sections are sorted so that minimal future references are -required, but it's unavoidable.

-

The actual "tutorial order" of the book is the -Examples chapter. Each section of that chapter -breaks down one of the provided examples in the examples -directory of the -repository. We go over what sections of the book you'll need to have read for -the example code to make sense, and also how we apply the general concepts -described in the book to the specific example cases.

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/00-introduction/04-hello-magic.html b/docs/00-introduction/04-hello-magic.html deleted file mode 100644 index 2d8fb46..0000000 --- a/docs/00-introduction/04-hello-magic.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - Hello, Magic - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Hello, Magic

-

So we know all the steps to build our source, we just need some source.

-

We're beginners, so we'll start small. With normal programming there's usually a -console available, so the minimal program prints "Hello, world" to the terminal. -On a GBA we don't have a terminal and standard out and all that, so the minimal -program draws a red, blue, and green dot to the screen.

-

At the lowest level of device programming, it's all Magic -Numbers. You write -special values to special places and then the hardware does something. A clear -API makes every magic number and magic location easy to understand. A clear and -good API also prevents you from using the wrong magic number in the wrong place -and causing problems for yourself.

-

This is the minimal example to just test that our build system is all set, so -just this once we'll go full magic number crazy town, for fun. Ready? Here -goes:

-

hello_magic.rs:

-
#![feature(start)]
-#![no_std]
-
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-  loop {}
-}
-
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
-  unsafe {
-    (0x400_0000 as *mut u16).write_volatile(0x0403);
-    (0x600_0000 as *mut u16).offset(120 + 80 * 240).write_volatile(0x001F);
-    (0x600_0000 as *mut u16).offset(136 + 80 * 240).write_volatile(0x03E0);
-    (0x600_0000 as *mut u16).offset(120 + 96 * 240).write_volatile(0x7C00);
-    loop {}
-  }
-}
-
-

Throw that into your project skeleton, build the program, and give it a run. You -should see a red, green, and blue dot close-ish to the middle of the screen. If -you don't, something already went wrong. Double check things, phone a friend, -write your senators, try asking Lokathor or Ketsuban on the Rust Community -Discord, until you're eventually able to -get your three dots going.

-

Of course, I'm sure you want to know why those numbers are the numbers to use. -Well that's what the whole rest of the book is about!

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/00-introduction/05-newtype.html b/docs/00-introduction/05-newtype.html deleted file mode 100644 index 83e4d8f..0000000 --- a/docs/00-introduction/05-newtype.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - Newtype - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Newtype

-

There's one thing I want to get out of the way near the start of the book and it -didn't really have a good fit anywhere else in the book so it goes right here.

-

We're talking about the "Newtype Pattern"!

-

Now, I told you to read the Rust Book before you read this book, and I'm sure -you're all good students who wouldn't sneak into this book without doing the -required reading, so I'm sure you all remember exactly what I'm talking about, -because they touch on the newtype concept in the book twice, in two very long -named sections:

- -

...Yeah... The Rust Book doesn't know how to make a short sub-section name to -save its life. Shame.

-

Newtype Basics

-

So, we have all these pieces of data, and we want to keep them separated, and we -don't wanna pay the cost for it at runtime. Well, we're in luck, we can pay the -cost at compile time.

-

-# #![allow(unused_variables)]
-#fn main() {
-pub struct PixelColor(u16);
-#}
-

Ah, except that, as I'm sure you remember from The -Rustonomicon -(and from the -RFC -too, of course), if we have a single field struct that's sometimes different -from having just the bare value, so we should be using #[repr(transparent)] -with our newtypes.

-

-# #![allow(unused_variables)]
-#fn main() {
-#[repr(transparent)]
-pub struct PixelColor(u16);
-#}
-

Ah, and of course we'll need to make it so you can unwrap the value:

-

-# #![allow(unused_variables)]
-#fn main() {
-#[repr(transparent)]
-pub struct PixelColor(u16);
-
-impl From<PixelColor> for u16 {
-  fn from(color: PixelColor) -> u16 {
-    color.0
-  }
-}
-#}
-

And then we'll need to do that same thing for every other newtype we want.

-

Except there's only two tiny parts that actually differ between newtype -declarations: the new name and the base type. All the rest is just the same rote -code over and over. Generating piles and piles of boilerplate code? Sounds like -a job for a macro to me!

-

Making It A Macro

-

The most basic version of the macro we want goes like this:

-

-# #![allow(unused_variables)]
-#fn main() {
-#[macro_export]
-macro_rules! newtype {
-  ($new_name:ident, $old_name:ident) => {
-    #[repr(transparent)]
-    pub struct $new_name($old_name);
-  };
-}
-#}
-

Except we also want to be able to add attributes (which includes doc comments), -so we upgrade our macro a bit:

-

-# #![allow(unused_variables)]
-#fn main() {
-#[macro_export]
-macro_rules! newtype {
-  ($(#[$attr:meta])* $new_name:ident, $old_name:ident) => {
-    $(#[$attr])*
-    #[repr(transparent)]
-    pub struct $new_name($old_name);
-  };
-}
-#}
-

And we want to automatically add the ability to turn the wrapper type back into -the wrapped type.

-

-# #![allow(unused_variables)]
-#fn main() {
-#[macro_export]
-macro_rules! newtype {
-  ($(#[$attr:meta])* $new_name:ident, $old_name:ident) => {
-    $(#[$attr])*
-    #[repr(transparent)]
-    pub struct $new_name($old_name);
-    
-    impl From<$new_name> for $old_name {
-      fn from(x: $new_name) -> $old_name {
-        x.0
-      }
-    }
-  };
-}
-#}
-

That seems like enough for all of our examples, so we'll stop there. We could -add more things, such as making the From impl optional (because what if you -shouldn't unwrap it for some weird reason?), allowing for more precise -visibility controls (on both the newtype overall and the inner field), and maybe -even other things I can't think of right now. We won't really need those in our -example code for this book, so it's probably nicer to just keep the macro -simpler and quit while we're ahead.

-

As a reminder: remember that macros have to appear before they're invoked in -your source, so the newtype macro will always have to be at the very top of -your file, or in a module that's declared before other modules and code.

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/00-introduction/06-help_and_resources.html b/docs/00-introduction/06-help_and_resources.html deleted file mode 100644 index 947acdf..0000000 --- a/docs/00-introduction/06-help_and_resources.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - Help and Resources - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Help and Resources

-

Help

-

So you're stuck on a problem and the book doesn't say what to do. Where can you -find out more?

-

The first place I would suggest is the Rust Community -Discord. If it's a general Rust question -then you can ask anyone in any channel you feel is appropriate. If it's GBA -specific then you can try asking me (Lokathor) or Ketsuban in the #gamedev -channel.

-

Emulators

-

You certainly might want to eventually write a game that you can put on a flash -cart and play on real hardware, but for most of your development you'll probably -want to be using an emulator for testing, because you don't have to fiddle with -cables and all that.

-

In terms of emulators, you want to be using -mGBA, and you want to be using the 0.7 Beta -1 or later. This update -lets you run raw ELF files, which means that you can have full debug symbols -available while you're debugging problems.

-

Information Resources

-

Ketsuban and I didn't magically learn this all from nowhere, we read various -technical manuals and guides ourselves and then distilled the knowledge (usually -oriented towards C and C++) into this book for Rust.

-

We have personally used some or all of the following:

-
    -
  • GBATEK: This is the resource. It -covers not only the GBA, but also the DS and DSi, and also a run down of ARM -assembly (32-bit and 16-bit opcodes). The link there is to the 2.9b version on -problemkaputt.de (the official home of the document), but if you just google -for gbatek the top result is for the 2.5 version on akkit.org, so make sure -you're looking at the newest version. Sometimes problemkaputt.de is a little -sluggish so I've also mirrored the 2.9b -version on my own site as well. GBATEK is rather large, over 2mb of text, so -if you're on a phone or similar you might want to save an offline copy to go -easy on your data usage.
  • -
  • TONC: While GBATEK is basically just a -huge tech specification, TONC is an actual guide on how to make sense of the -GBA's abilities and organize it into a game. It's written for C of course, but -as a Rust programmer you should always be practicing your ability to read C -code anyway. It's the programming equivalent of learning Latin because all the -old academic books are written in Latin.
  • -
  • CowBite: This is -more like GBATEK, and it's less complete, but it mixes in a little more -friendly explanation of things in between the hardware spec parts.
  • -
-

And I haven't had time to look at it myself, The Audio -Advance seems to be very good. It explains in depth -how you can get audio working on the GBA. Note that the table of contents for -each page goes along the top instead of down the side.

-

Non-Rust GBA Community

-

There's also the GBADev.org site, which has a forum -and everything. They're coding in C and C++, but you can probably overcome that -difference with a little work on your part.

-

I also found a place called -GBATemp, which -seems to have a more active forum but less of a focus on actual coding.

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/01-limitations/00-index.html b/docs/01-limitations/00-index.html deleted file mode 100644 index a0dcf4f..0000000 --- a/docs/01-limitations/00-index.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Limitations - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

GBA Limitations

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/01-limitations/01-no_floats.html b/docs/01-limitations/01-no_floats.html deleted file mode 100644 index bcbedc1..0000000 --- a/docs/01-limitations/01-no_floats.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - No Floats - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

No Floats

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/01-limitations/02-core_only.html b/docs/01-limitations/02-core_only.html deleted file mode 100644 index f56f156..0000000 --- a/docs/01-limitations/02-core_only.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Core Only - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Core Only

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/01-limitations/03-volatile_destination.html b/docs/01-limitations/03-volatile_destination.html deleted file mode 100644 index 925762f..0000000 --- a/docs/01-limitations/03-volatile_destination.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Volatile Destination - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Volatile Destination

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/00-index.html b/docs/02-concepts/00-index.html deleted file mode 100644 index 2b6a887..0000000 --- a/docs/02-concepts/00-index.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Concepts - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Broad Concepts

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/01-cpu.html b/docs/02-concepts/01-cpu.html deleted file mode 100644 index e148a21..0000000 --- a/docs/02-concepts/01-cpu.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - CPU - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

CPU

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/02-bios.html b/docs/02-concepts/02-bios.html deleted file mode 100644 index a574dc0..0000000 --- a/docs/02-concepts/02-bios.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - BIOS - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

BIOS

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/03-wram.html b/docs/02-concepts/03-wram.html deleted file mode 100644 index a20f834..0000000 --- a/docs/02-concepts/03-wram.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Work RAM - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Work RAM

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/04-io-registers.html b/docs/02-concepts/04-io-registers.html deleted file mode 100644 index c369774..0000000 --- a/docs/02-concepts/04-io-registers.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - IO Registers - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

IO Registers

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/05-palram.html b/docs/02-concepts/05-palram.html deleted file mode 100644 index f89b731..0000000 --- a/docs/02-concepts/05-palram.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Palette RAM - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Palette RAM

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/06-vram.html b/docs/02-concepts/06-vram.html deleted file mode 100644 index a44a38b..0000000 --- a/docs/02-concepts/06-vram.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Video RAM - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Video RAM

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/07-oam.html b/docs/02-concepts/07-oam.html deleted file mode 100644 index 1daa1b5..0000000 --- a/docs/02-concepts/07-oam.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Object Attribute Memory - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Object Attribute Memory

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/08-rom.html b/docs/02-concepts/08-rom.html deleted file mode 100644 index 001bed1..0000000 --- a/docs/02-concepts/08-rom.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Game Pak ROM / Flash ROM - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Game Pak ROM / Flash ROM

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/02-concepts/09-sram.html b/docs/02-concepts/09-sram.html deleted file mode 100644 index 811a486..0000000 --- a/docs/02-concepts/09-sram.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Save RAM - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Save RAM

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/03-video/00-index.html b/docs/03-video/00-index.html deleted file mode 100644 index cae5504..0000000 --- a/docs/03-video/00-index.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Video - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Video

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/03-video/01-rgb15.html b/docs/03-video/01-rgb15.html deleted file mode 100644 index d530da5..0000000 --- a/docs/03-video/01-rgb15.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - RBG15 Color - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

RBG15 Color

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/03-video/TODO.html b/docs/03-video/TODO.html deleted file mode 100644 index 071161e..0000000 --- a/docs/03-video/TODO.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - TODO - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

TODO

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/04-non-video/00-index.html b/docs/04-non-video/00-index.html deleted file mode 100644 index 5fe83b5..0000000 --- a/docs/04-non-video/00-index.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Non-Video - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Non-Video

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/04-non-video/01-buttons.html b/docs/04-non-video/01-buttons.html deleted file mode 100644 index 6c29b3d..0000000 --- a/docs/04-non-video/01-buttons.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Buttons - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Buttons

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/04-non-video/02-timers.html b/docs/04-non-video/02-timers.html deleted file mode 100644 index 127a7ff..0000000 --- a/docs/04-non-video/02-timers.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Timers - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Timers

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/04-non-video/03-dma.html b/docs/04-non-video/03-dma.html deleted file mode 100644 index 6463f1b..0000000 --- a/docs/04-non-video/03-dma.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Direct Memory Access - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Direct Memory Access

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/04-non-video/04-sound.html b/docs/04-non-video/04-sound.html deleted file mode 100644 index b3c9d3d..0000000 --- a/docs/04-non-video/04-sound.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Sound - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Sound

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/04-non-video/05-interrupts.html b/docs/04-non-video/05-interrupts.html deleted file mode 100644 index 5d98dc2..0000000 --- a/docs/04-non-video/05-interrupts.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Interrupts - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Interrupts

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/04-non-video/06-network.html b/docs/04-non-video/06-network.html deleted file mode 100644 index 386ba59..0000000 --- a/docs/04-non-video/06-network.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Network - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Network

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/04-non-video/07-game_pak.html b/docs/04-non-video/07-game_pak.html deleted file mode 100644 index 874877d..0000000 --- a/docs/04-non-video/07-game_pak.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Game Pak - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Game Pak

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/05-examples/00-index.html b/docs/05-examples/00-index.html deleted file mode 100644 index eae8eb8..0000000 --- a/docs/05-examples/00-index.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Examples - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

Examples

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/05-examples/01-hello_magic.html b/docs/05-examples/01-hello_magic.html deleted file mode 100644 index 841e7fd..0000000 --- a/docs/05-examples/01-hello_magic.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - hello_magic - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

hello_magic

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/05-examples/02-hello_world.html b/docs/05-examples/02-hello_world.html deleted file mode 100644 index 9d46013..0000000 --- a/docs/05-examples/02-hello_world.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - hello_world - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

hello_world

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/05-examples/03-light_cycle.html b/docs/05-examples/03-light_cycle.html deleted file mode 100644 index 4f92214..0000000 --- a/docs/05-examples/03-light_cycle.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - light_cycle - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

light_cycle

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/05-examples/04-bg_demo.html b/docs/05-examples/04-bg_demo.html deleted file mode 100644 index 9dcf60f..0000000 --- a/docs/05-examples/04-bg_demo.html +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - bg_demo - Rust GBA Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - -
-
-

bg_demo

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/00-introduction/03-development-setup.html b/docs/development-setup.html similarity index 72% rename from docs/00-introduction/03-development-setup.html rename to docs/development-setup.html index cfb680b..65d01be 100644 --- a/docs/00-introduction/03-development-setup.html +++ b/docs/development-setup.html @@ -9,21 +9,21 @@ - - - - - + + + + + - + - - - + + + @@ -32,7 +32,7 @@ - +
@@ -105,7 +105,7 @@

Rust GBA Guide

@@ -286,19 +286,47 @@ ROM is patched in place, so we don't even need to specify a new destination.Of course, you probably want to make a script for all that, but it's up to you. On our own project we have it mostly set up within a Makefile.toml which runs using the cargo-make plugin.

+

Checking Your Setup

+

As I said, you need some source code to compile just to check that your +compilation pipeline is working. Here's a sample file that just puts three dots +on the screen without depending on any crates or anything at all.

+

hello_magic.rs:

+
#![no_std]
+#![feature(start)]
+
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+  loop {}
+}
+
+#[start]
+fn main(_argc: isize, _argv: *const *const u8) -> isize {
+  unsafe {
+    (0x400_0000 as *mut u16).write_volatile(0x0403);
+    (0x600_0000 as *mut u16).offset(120 + 80 * 240).write_volatile(0x001F);
+    (0x600_0000 as *mut u16).offset(136 + 80 * 240).write_volatile(0x03E0);
+    (0x600_0000 as *mut u16).offset(120 + 96 * 240).write_volatile(0x7C00);
+    loop {}
+  }
+}
+
+

Throw that into your project skeleton, build the program, and give it a run. You +should see a red, green, and blue dot close-ish to the middle of the screen. If +you don't, something already went wrong. Double check things, phone a friend, +write your senators, try asking Lokathor or Ketsuban on the Rust Community +Discord, until you're eventually able to +get your three dots going.

+

Of course, I'm sure you want to know why those numbers are the numbers to use. +Well that's what the whole rest of the book is about!