checkers!

This commit is contained in:
Lokathor 2018-12-05 21:56:39 -07:00
parent e9b62f1832
commit 9689394d75
30 changed files with 3337 additions and 1174 deletions

View file

@ -1,4 +1,4 @@
# memory_game
# Making A Memory Game
For this example to show off our new skills we'll make a "memory" game. The idea
is that there's some face down cards and you pick one, it flips, you pick a
@ -6,207 +6,310 @@ second, if they match they both go away, if they don't match they both turn back
face down. The player keeps going until all the cards are gone, then we'll deal
the cards again.
For this example, I started with the `light_cycle.rs` example and then just
copied it into a new file, `memory_game.rs`. Then I added most all the code from
the previous sections right into that file, so we'll assume that all those
definitions are in scope.
There are many steps to do to get such a simple seeming game going. In fact I
stumbled a bit myself when trying to get things set up and going despite having
written and explained all the parts so far. Accordingly, we'll take each part
very slowly, and review things as we build up our game.
## Getting Some Images
First we need some images to show! Let's have one for our little selector thingy
that we'll move around to pick cards with. How about some little triangles at
the corner of a square like on a picture frame.
We'll start back with a nearly blank file, calling it `memory_game.rs`:
```rust
#[rustfmt::skip]
pub const CARD_SELECTOR: Tile4bpp = Tile4bpp {
data : [
0x44400444,
0x44000044,
0x40000004,
0x00000000,
0x00000000,
0x40000004,
0x44000044,
0x44400444
]
};
```
#![feature(start)]
#![no_std]
That weird looking attribute keeps rustfmt from spreading out the values, so
that we can see it as an ASCII art. Now that we understand what an individual
tile looks like, let's add some mono-color squares.
```rust
#[rustfmt::skip]
pub const FULL_ONE: Tile4bpp = Tile4bpp {
data : [
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
]
};
#[rustfmt::skip]
pub const FULL_TWO: Tile4bpp = Tile4bpp {
data : [
0x22222222,
0x22222222,
0x22222222,
0x22222222,
0x22222222,
0x22222222,
0x22222222,
0x22222222
]
};
#[rustfmt::skip]
pub const FULL_THREE: Tile4bpp = Tile4bpp {
data : [
0x33333333,
0x33333333,
0x33333333,
0x33333333,
0x33333333,
0x33333333,
0x33333333,
0x33333333
]
};
```
We can control the rest with palbank selection. Since there's 16 palbanks,
that's 48 little colored squares we can make, and 16 different selector colors,
which should be plenty in both cases.
## Setup The Images
### Arrange the PALRAM
Alright, so, as we went over, the first step is to make sure that we've got our
palette data in order. We'll be using this to set our palette values.
```rust
pub fn set_bg_palette(slot: usize, color: u16) {
assert!(slot < 256);
unsafe { PALRAM_BG_BASE.offset(slot as isize).write(color) }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
```
Should the type of `slot` be changed to `u8` instead of `usize`? Well, maybe.
Let's not worry about it at the moment.
Of course, we don't need to set the color black, all the values start as black.
We just need to set the other colors we'll be wanting. For this demo, we'll just
use the same basic colors for both the BG and Object stuff.
```rust
pub fn init_palette() {
// palbank 0: black/white/gray
set_bg_palette(2, rgb16(31, 31, 31));
set_bg_palette(3, rgb16(15, 15, 15));
// palbank 1 is reds
set_bg_palette(1 * 16 + 1, rgb16(31, 0, 0));
set_bg_palette(1 * 16 + 2, rgb16(22, 0, 0));
set_bg_palette(1 * 16 + 3, rgb16(10, 0, 0));
// palbank 2 is greens
set_bg_palette(2 * 16 + 1, rgb16(0, 31, 0));
set_bg_palette(2 * 16 + 2, rgb16(0, 22, 0));
set_bg_palette(2 * 16 + 3, rgb16(0, 10, 0));
// palbank 2 is blues
set_bg_palette(3 * 16 + 1, rgb16(0, 0, 31));
set_bg_palette(3 * 16 + 2, rgb16(0, 0, 22));
set_bg_palette(3 * 16 + 3, rgb16(0, 0, 10));
// Direct copy all BG selections into OBJ palette too
let mut bgp = PALRAM_BG_BASE;
let mut objp = PALRAM_OBJECT_BASE;
for _ in 0..(4 * 16) {
objp.write(bgp.read());
bgp = bgp.offset(1);
objp = objp.offset(1);
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
loop {
// TODO the whole thing
}
}
```
### Arrange the Objects
## Displaying A Background
So, time to think about objects. I'm thinking we'll have 13 objects in use. One
for the selector, and then 12 for the cards (a simple grid that's 4 wide and 3
tall).
First let's try to get a background going. We'll display a simple checker
pattern just so that we know that we did something.
We want a way to easily clear away all the objects that we're not using, which
is all the slots starting at some index and then going to the end.
Remember, backgrounds have the following essential components:
* Background Palette
* Background Tiles
* Screenblock
* IO Registers
### Background Palette
To write to the background palette memory we'll want to name a `VolatilePtr` for
it. We'll probably also want to be able to cast between different types either
right away or later in this program, so we'll add a method for that.
```rust
pub fn clear_objects_starting_with(base_slot: usize) {
let mut obj = ObjectAttributes::default();
obj.set_rendering(ObjectRenderMode::Disabled);
for s in base_slot..128 {
set_object_attributes(s, obj);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct VolatilePtr<T>(pub *mut T);
impl<T> VolatilePtr<T> {
pub unsafe fn read(&self) -> T {
core::ptr::read_volatile(self.0)
}
pub unsafe fn write(&self, data: T) {
core::ptr::write_volatile(self.0, data);
}
pub fn offset(self, count: isize) -> Self {
VolatilePtr(self.0.wrapping_offset(count))
}
pub fn cast<Z>(self) -> VolatilePtr<Z> {
VolatilePtr(self.0 as *mut Z)
}
}
```
Next we set out the positions of our cards. We set the tile data we need, and
then assign the object attributes to go with it. For this, we'll make the
position finder function be its own thing since we'll also need it for the card
selector to move around. Finally, we set our selector as being at position 0,0
of the card grid.
Now we give ourselves an easy way to write a color into a palbank slot.
```rust
pub fn position_of_card(card_col: usize, card_row: usize) -> (u16, u16) {
(10 + card_col as u16 * 17, 5 + card_row as u16 * 15)
pub const BACKGROUND_PALETTE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16);
pub fn set_bg_palette_4bpp(palbank: usize, slot: usize, color: u16) {
assert!(palbank < 16);
assert!(slot > 0 && slot < 16);
unsafe {
BACKGROUND_PALETTE
.cast::<[u16; 16]>()
.offset(palbank as isize)
.cast::<u16>()
.offset(slot as isize)
.write(color);
}
}
```
And of course we need to bring back in our ability to build color values, as
well as a few named colors to start us off:
```rust
pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
blue << 10 | green << 5 | red
}
pub fn arrange_cards() {
set_obj_tile_4bpp(1, FULL_ONE);
set_obj_tile_4bpp(2, FULL_TWO);
set_obj_tile_4bpp(3, FULL_THREE);
let mut obj = ObjectAttributes::default();
obj.set_tile_index(2); // along with palbank0, this is a white card
for card_row in 0..3 {
for card_col in 0..4 {
let (col, row) = position_of_card(card_col, card_row);
obj.set_column(col);
obj.set_row(row);
set_object_attributes(1 + card_col as usize + (card_row as usize * 3), obj);
pub const WHITE: u16 = rgb16(31, 31, 31);
pub const LIGHT_GRAY: u16 = rgb16(25, 25, 25);
pub const DARK_GRAY: u16 = rgb16(15, 15, 15);
```
Which _finally_ allows us to set our palette colors in `main`:
```rust
fn main(_argc: isize, _argv: *const *const u8) -> isize {
set_bg_palette_4bpp(0, 1, WHITE);
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
set_bg_palette_4bpp(0, 3, DARK_GRAY);
```
### Background Tiles
So we'll want some light gray tiles and some dark gray tiles. We could use a
single tile and then swap it between palbanks to do the color selection, but for
now we'll just use two different tiles, since we've got tons of tile space to
spare.
```rust
#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct Tile4bpp {
pub data: [u32; 8],
}
pub const ALL_TWOS: Tile4bpp = Tile4bpp {
data: [
0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222,
],
};
pub const ALL_THREES: Tile4bpp = Tile4bpp {
data: [
0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333,
],
};
```
And then we have to have a way to put the tiles into video memory:
```rust
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct Charblock4bpp {
pub data: [Tile4bpp; 512],
}
pub const VRAM: VolatilePtr<Charblock4bpp> = VolatilePtr(0x0600_0000 as *mut Charblock4bpp);
pub fn set_bg_tile_4bpp(charblock: usize, index: usize, tile: Tile4bpp) {
assert!(charblock < 4);
assert!(index < 512);
unsafe { VRAM.offset(charblock as isize).cast::<Tile4bpp>().offset(index as isize).write(tile) }
}
```
And finally, we can call that within `main`:
```rust
fn main(_argc: isize, _argv: *const *const u8) -> isize {
// bg palette
set_bg_palette_4bpp(0, 1, WHITE);
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
set_bg_palette_4bpp(0, 3, DARK_GRAY);
// bg tiles
set_bg_tile_4bpp(0, 0, ALL_TWOS);
set_bg_tile_4bpp(0, 1, ALL_THREES);
```
### Setup A Screenblock
Screenblocks are a little weird because they take the same space as the
charblocks (8 screenblocks per charblock). The GBA will let you mix and match
and it's up to you to keep it all straight. We're using tiles at the base of
charblock 0, so we'll place our screenblock at the base of charblock 1.
First, we have to be able to make one single screenblock entry at a time:
```rust
#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct RegularScreenblockEntry(u16);
impl RegularScreenblockEntry {
pub const SCREENBLOCK_ENTRY_TILE_ID_MASK: u16 = 0b11_1111_1111;
pub fn from_tile_id(id: u16) -> Self {
RegularScreenblockEntry(id & Self::SCREENBLOCK_ENTRY_TILE_ID_MASK)
}
}
```
And then with 32x32 of these things we'll have a whole screenblock. Now, we
probably won't actually make values of the screenblock type itself, but we at
least need it to have the type declared with the correct size so that we can
move our pointers around by the right amount.
```rust
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct RegularScreenblock {
pub data: [RegularScreenblockEntry; 32 * 32],
}
```
Alright, so, as I said those things are kinda big, we don't really want to be
building them up on the stack if we can avoid it, so we'll write one straight
into memory at the correct location.
```rust
pub fn checker_screenblock(slot: usize, a_entry: RegularScreenblockEntry, b_entry: RegularScreenblockEntry) {
let mut p = VRAM.cast::<RegularScreenblock>().offset(slot as isize).cast::<RegularScreenblockEntry>();
let mut checker = true;
for _row in 0..32 {
for _col in 0..32 {
unsafe { p.write(if checker { a_entry } else { b_entry }) };
p = p.offset(1);
checker = !checker;
}
checker = !checker;
}
}
pub fn init_selector() {
set_obj_tile_4bpp(0, CARD_SELECTOR);
let mut obj = ObjectAttributes::default();
let (col, row) = position_of_card(0, 0);
obj.set_column(col);
obj.set_row(row);
set_object_attributes(0, obj);
}
```
### Arrange the Background
And then we add this into `main`
TODO
```rust
// screenblock
let light_entry = RegularScreenblockEntry::from_tile_id(0);
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
checker_screenblock(8, light_entry, dark_entry);
```
## Shuffling The Cards
### Background IO Registers
TODO
Our most important step is of course the IO register step. There's four
different background layers, but each of them has the same format for their
control register. For the moment, all that we care about is being able to set
the "screen base block" value.
## Picking One Card
```rust
#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct BackgroundControlSetting(u16);
TODO
impl BackgroundControlSetting {
pub fn from_base_block(sbb: u16) -> Self {
BackgroundControlSetting(sbb << 8)
}
}
## Picking The Second Card
pub const BG0CNT: VolatilePtr<BackgroundControlSetting> = VolatilePtr(0x400_0008 as *mut BackgroundControlSetting);
```
TODO
And... that's all it takes for us to be able to add a line into `main`
## Resetting The Game
```rust
// bg0 control
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
```
TODO
### Set The Display Control Register
We're finally ready to set the display control register and get things going.
We've slightly glossed over it so far, but when the GBA is first booted most
everything within the address space will be all zeroed. However, the display
control register has the "Force VBlank" bit enabled by the BIOS, giving you a
moment to put the memory in place that you'll need for the first frame.
So, now that have got all of our memory set, we'll overwrite the initial
display control register value with what we'll call "just enable bg0".
```rust
#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct DisplayControlSetting(u16);
impl DisplayControlSetting {
pub const JUST_ENABLE_BG0: DisplayControlSetting = DisplayControlSetting(1 << 8);
}
pub const DISPCNT: VolatilePtr<DisplayControlSetting> = VolatilePtr(0x0400_0000 as *mut DisplayControlSetting);
```
And so finally we have a complete `main`
```rust
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
// bg palette
set_bg_palette_4bpp(0, 1, WHITE);
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
set_bg_palette_4bpp(0, 3, DARK_GRAY);
// bg tiles
set_bg_tile_4bpp(0, 0, ALL_TWOS);
set_bg_tile_4bpp(0, 1, ALL_THREES);
// screenblock
let light_entry = RegularScreenblockEntry::from_tile_id(0);
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
checker_screenblock(8, light_entry, dark_entry);
// bg0 control
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
// Display Control
unsafe { DISPCNT.write(DisplayControlSetting::JUST_ENABLE_BG0) };
loop {
// TODO the whole thing
}
}
```
And _It works, Marty! It works!_
![screenshot_checkers](screenshot_checkers.png)
We've got more to go, but we're well on our way.

View file

@ -123,14 +123,14 @@ everything all lined up and into place anyway.
The final step is to assign the correct attributes to an object. Each object has
three `u16` values that make up its overall attributes.
Before we go into the details, I want to remind you that the hardware will
attempt to process every single object every single frame, and also that all of
the GBA's memory is cleared to 0 at startup. Why do these two things matter
right now? As you'll see in a second an "all zero" set of object attributes
causes an 8x8 object to appear at 0,0 using object tile index 0. This is usually
_not_ what you want your unused objects to do. When your game first starts you
should take a moment to mark any objects you won't be using as objects to not
render.
Before we go into the details, I want to bring up that the hardware will attempt
to process every single object every single frame if the object layer is
enabled, and also that all of the GBA's object memory is cleared to 0 at
startup. Why do these two things matter right now? As you'll see in a second an
"all zero" set of object attributes causes an 8x8 object to appear at 0,0 using
object tile index 0. This is usually _not_ what you want your unused objects to
do. When your game first starts you should take a moment to mark any objects you
won't be using as objects to not render.
### ObjectAttributes.attr0

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html" class="active"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html" class="active"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html" class="active"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html" class="active"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html" class="active"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html" class="active"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html" class="active"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html" class="active"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html" class="active"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html" class="active"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html" class="active"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html" class="active"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html" class="active"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html" class="active"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html" class="active"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html" class="active"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html" class="active"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html" class="active"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html" class="active"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html" class="active"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html" class="active"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html" class="active"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html" class="active"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html" class="active"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html" class="active"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html" class="active"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

1232
docs/ch03/gba_prng.html Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,201 +0,0 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>GBA RNG - Rust GBA Guide</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body class="light">
<!-- Provide site root to javascript -->
<script type="text/javascript">var path_to_root = "../";</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = 'light'; }
document.body.className = theme;
document.querySelector('html').className = theme + ' js';
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html" class="active"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar" class="menu-bar">
<div id="menu-bar-sticky-container">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light <span class="default">(default)</span></button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Rust GBA Guide</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<a class="header" href="#gba-rng" id="gba-rng"><h1>GBA RNG</h1></a>
<p>TODO</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../ch03/regular_objects.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../ch03/memory_game.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a href="../ch03/regular_objects.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a href="../ch03/memory_game.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html" class="active"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html" class="active"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html" class="active"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html" class="active"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -136,15 +136,300 @@
<div id="content" class="content">
<main>
<a class="header" href="#memory_game" id="memory_game"><h1>memory_game</h1></a>
<p>TODO</p>
<a class="header" href="#making-a-memory-game" id="making-a-memory-game"><h1>Making A Memory Game</h1></a>
<p>For this example to show off our new skills we'll make a &quot;memory&quot; game. The idea
is that there's some face down cards and you pick one, it flips, you pick a
second, if they match they both go away, if they don't match they both turn back
face down. The player keeps going until all the cards are gone, then we'll deal
the cards again.</p>
<p>There are many steps to do to get such a simple seeming game going. In fact I
stumbled a bit myself when trying to get things set up and going despite having
written and explained all the parts so far. Accordingly, we'll take each part
very slowly, and review things as we build up our game.</p>
<p>We'll start back with a nearly blank file, calling it <code>memory_game.rs</code>:</p>
<pre><pre class="playpen"><code class="language-rust">#![feature(start)]
#![no_std]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}
}
#[start]
fn main(_argc: isize, _argv: *const *const u8) -&gt; isize {
loop {
// TODO the whole thing
}
}
</code></pre></pre>
<a class="header" href="#displaying-a-background" id="displaying-a-background"><h2>Displaying A Background</h2></a>
<p>First let's try to get a background going. We'll display a simple checker
pattern just so that we know that we did something.</p>
<p>Remember, backgrounds have the following essential components:</p>
<ul>
<li>Background Palette</li>
<li>Background Tiles</li>
<li>Screenblock</li>
<li>IO Registers</li>
</ul>
<a class="header" href="#background-palette" id="background-palette"><h3>Background Palette</h3></a>
<p>To write to the background palette memory we'll want to name a <code>VolatilePtr</code> for
it. We'll probably also want to be able to cast between different types either
right away or later in this program, so we'll add a method for that.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct VolatilePtr&lt;T&gt;(pub *mut T);
impl&lt;T&gt; VolatilePtr&lt;T&gt; {
pub unsafe fn read(&amp;self) -&gt; T {
core::ptr::read_volatile(self.0)
}
pub unsafe fn write(&amp;self, data: T) {
core::ptr::write_volatile(self.0, data);
}
pub fn offset(self, count: isize) -&gt; Self {
VolatilePtr(self.0.wrapping_offset(count))
}
pub fn cast&lt;Z&gt;(self) -&gt; VolatilePtr&lt;Z&gt; {
VolatilePtr(self.0 as *mut Z)
}
}
#}</code></pre></pre>
<p>Now we give ourselves an easy way to write a color into a palbank slot.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
pub const BACKGROUND_PALETTE: VolatilePtr&lt;u16&gt; = VolatilePtr(0x500_0000 as *mut u16);
pub fn set_bg_palette_4bpp(palbank: usize, slot: usize, color: u16) {
assert!(palbank &lt; 16);
assert!(slot &gt; 0 &amp;&amp; slot &lt; 16);
unsafe {
BACKGROUND_PALETTE
.cast::&lt;[u16; 16]&gt;()
.offset(palbank as isize)
.cast::&lt;u16&gt;()
.offset(slot as isize)
.write(color);
}
}
#}</code></pre></pre>
<p>And of course we need to bring back in our ability to build color values, as
well as a few named colors to start us off:</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
pub const fn rgb16(red: u16, green: u16, blue: u16) -&gt; u16 {
blue &lt;&lt; 10 | green &lt;&lt; 5 | red
}
pub const WHITE: u16 = rgb16(31, 31, 31);
pub const LIGHT_GRAY: u16 = rgb16(25, 25, 25);
pub const DARK_GRAY: u16 = rgb16(15, 15, 15);
#}</code></pre></pre>
<p>Which <em>finally</em> allows us to set our palette colors in <code>main</code>:</p>
<pre><pre class="playpen"><code class="language-rust">fn main(_argc: isize, _argv: *const *const u8) -&gt; isize {
set_bg_palette_4bpp(0, 1, WHITE);
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
set_bg_palette_4bpp(0, 3, DARK_GRAY);
</code></pre></pre>
<a class="header" href="#background-tiles" id="background-tiles"><h3>Background Tiles</h3></a>
<p>So we'll want some light gray tiles and some dark gray tiles. We could use a
single tile and then swap it between palbanks to do the color selection, but for
now we'll just use two different tiles, since we've got tons of tile space to
spare.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct Tile4bpp {
pub data: [u32; 8],
}
pub const ALL_TWOS: Tile4bpp = Tile4bpp {
data: [
0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222,
],
};
pub const ALL_THREES: Tile4bpp = Tile4bpp {
data: [
0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333,
],
};
#}</code></pre></pre>
<p>And then we have to have a way to put the tiles into video memory:</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct Charblock4bpp {
pub data: [Tile4bpp; 512],
}
pub const VRAM: VolatilePtr&lt;Charblock4bpp&gt; = VolatilePtr(0x0600_0000 as *mut Charblock4bpp);
pub fn set_bg_tile_4bpp(charblock: usize, index: usize, tile: Tile4bpp) {
assert!(charblock &lt; 4);
assert!(index &lt; 512);
unsafe { VRAM.offset(charblock as isize).cast::&lt;Tile4bpp&gt;().offset(index as isize).write(tile) }
}
#}</code></pre></pre>
<p>And finally, we can call that within <code>main</code>:</p>
<pre><pre class="playpen"><code class="language-rust">fn main(_argc: isize, _argv: *const *const u8) -&gt; isize {
// bg palette
set_bg_palette_4bpp(0, 1, WHITE);
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
set_bg_palette_4bpp(0, 3, DARK_GRAY);
// bg tiles
set_bg_tile_4bpp(0, 0, ALL_TWOS);
set_bg_tile_4bpp(0, 1, ALL_THREES);
</code></pre></pre>
<a class="header" href="#setup-a-screenblock" id="setup-a-screenblock"><h3>Setup A Screenblock</h3></a>
<p>Screenblocks are a little weird because they take the same space as the
charblocks (8 screenblocks per charblock). The GBA will let you mix and match
and it's up to you to keep it all straight. We're using tiles at the base of
charblock 0, so we'll place our screenblock at the base of charblock 1.</p>
<p>First, we have to be able to make one single screenblock entry at a time:</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct RegularScreenblockEntry(u16);
impl RegularScreenblockEntry {
pub const SCREENBLOCK_ENTRY_TILE_ID_MASK: u16 = 0b11_1111_1111;
pub fn from_tile_id(id: u16) -&gt; Self {
RegularScreenblockEntry(id &amp; Self::SCREENBLOCK_ENTRY_TILE_ID_MASK)
}
}
#}</code></pre></pre>
<p>And then with 32x32 of these things we'll have a whole screenblock. Now, we
probably won't actually make values of the screenblock type itself, but we at
least need it to have the type declared with the correct size so that we can
move our pointers around by the right amount.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct RegularScreenblock {
pub data: [RegularScreenblockEntry; 32 * 32],
}
#}</code></pre></pre>
<p>Alright, so, as I said those things are kinda big, we don't really want to be
building them up on the stack if we can avoid it, so we'll write one straight
into memory at the correct location.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
pub fn checker_screenblock(slot: usize, a_entry: RegularScreenblockEntry, b_entry: RegularScreenblockEntry) {
let mut p = VRAM.cast::&lt;RegularScreenblock&gt;().offset(slot as isize).cast::&lt;RegularScreenblockEntry&gt;();
let mut checker = true;
for _row in 0..32 {
for _col in 0..32 {
unsafe { p.write(if checker { a_entry } else { b_entry }) };
p = p.offset(1);
checker = !checker;
}
checker = !checker;
}
}
#}</code></pre></pre>
<p>And then we add this into <code>main</code></p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
// screenblock
let light_entry = RegularScreenblockEntry::from_tile_id(0);
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
checker_screenblock(8, light_entry, dark_entry);
#}</code></pre></pre>
<a class="header" href="#background-io-registers" id="background-io-registers"><h3>Background IO Registers</h3></a>
<p>Our most important step is of course the IO register step. There's four
different background layers, but each of them has the same format for their
control register. For the moment, all that we care about is being able to set
the &quot;screen base block&quot; value.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct BackgroundControlSetting(u16);
impl BackgroundControlSetting {
pub fn from_base_block(sbb: u16) -&gt; Self {
BackgroundControlSetting(sbb &lt;&lt; 8)
}
}
pub const BG0CNT: VolatilePtr&lt;BackgroundControlSetting&gt; = VolatilePtr(0x400_0008 as *mut BackgroundControlSetting);
#}</code></pre></pre>
<p>And... that's all it takes for us to be able to add a line into <code>main</code></p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
// bg0 control
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
#}</code></pre></pre>
<a class="header" href="#set-the-display-control-register" id="set-the-display-control-register"><h3>Set The Display Control Register</h3></a>
<p>We're finally ready to set the display control register and get things going.</p>
<p>We've slightly glossed over it so far, but when the GBA is first booted most
everything within the address space will be all zeroed. However, the display
control register has the &quot;Force VBlank&quot; bit enabled by the BIOS, giving you a
moment to put the memory in place that you'll need for the first frame.</p>
<p>So, now that have got all of our memory set, we'll overwrite the initial
display control register value with what we'll call &quot;just enable bg0&quot;.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct DisplayControlSetting(u16);
impl DisplayControlSetting {
pub const JUST_ENABLE_BG0: DisplayControlSetting = DisplayControlSetting(1 &lt;&lt; 8);
}
pub const DISPCNT: VolatilePtr&lt;DisplayControlSetting&gt; = VolatilePtr(0x0400_0000 as *mut DisplayControlSetting);
#}</code></pre></pre>
<p>And so finally we have a complete <code>main</code></p>
<pre><pre class="playpen"><code class="language-rust">#[start]
fn main(_argc: isize, _argv: *const *const u8) -&gt; isize {
// bg palette
set_bg_palette_4bpp(0, 1, WHITE);
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
set_bg_palette_4bpp(0, 3, DARK_GRAY);
// bg tiles
set_bg_tile_4bpp(0, 0, ALL_TWOS);
set_bg_tile_4bpp(0, 1, ALL_THREES);
// screenblock
let light_entry = RegularScreenblockEntry::from_tile_id(0);
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
checker_screenblock(8, light_entry, dark_entry);
// bg0 control
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
// Display Control
unsafe { DISPCNT.write(DisplayControlSetting::JUST_ENABLE_BG0) };
loop {
// TODO the whole thing
}
}
</code></pre></pre>
<p>And <em>It works, Marty! It works!</em></p>
<p><img src="screenshot_checkers.png" alt="screenshot_checkers" /></p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../ch03/gba_rng.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../ch03/gba_prng.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@ -158,7 +443,7 @@
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a href="../ch03/gba_rng.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a href="../ch03/gba_prng.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html" class="active"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html" class="active"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -204,28 +204,28 @@ the size of that type of tile. Like this:</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
pub fn bg_tile_4pp(base_block: usize, tile_index: usize) -&gt; Tile4bpp {
pub fn bg_tile_4bpp(base_block: usize, tile_index: usize) -&gt; Tile4bpp {
assert!(base_block &lt; 4);
assert!(tile_index &lt; 512);
let address = VRAM + size_of::&lt;Charblock4bpp&gt;() * base_block + size_of::&lt;Tile4bpp&gt;() * tile_index;
unsafe { VolatilePtr(address as *mut Tile4bpp).read() }
}
pub fn set_bg_tile_4pp(base_block: usize, tile_index: usize, tile: Tile4bpp) {
pub fn set_bg_tile_4bpp(base_block: usize, tile_index: usize, tile: Tile4bpp) {
assert!(base_block &lt; 4);
assert!(tile_index &lt; 512);
let address = VRAM + size_of::&lt;Charblock4bpp&gt;() * base_block + size_of::&lt;Tile4bpp&gt;() * tile_index;
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
}
pub fn bg_tile_8pp(base_block: usize, tile_index: usize) -&gt; Tile8bpp {
pub fn bg_tile_8bpp(base_block: usize, tile_index: usize) -&gt; Tile8bpp {
assert!(base_block &lt; 4);
assert!(tile_index &lt; 256);
let address = VRAM + size_of::&lt;Charblock8bpp&gt;() * base_block + size_of::&lt;Tile8bpp&gt;() * tile_index;
unsafe { VolatilePtr(address as *mut Tile8bpp).read() }
}
pub fn set_bg_tile_8pp(base_block: usize, tile_index: usize, tile: Tile8bpp) {
pub fn set_bg_tile_8bpp(base_block: usize, tile_index: usize, tile: Tile8bpp) {
assert!(base_block &lt; 4);
assert!(tile_index &lt; 256);
let address = VRAM + size_of::&lt;Charblock8bpp&gt;() * base_block + size_of::&lt;Tile8bpp&gt;() * tile_index;
@ -277,7 +277,7 @@ appropriately.</p>
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct RegularScreenblock {
data: [RegularScreenblockEntry; 32 * 32],
pub data: [RegularScreenblockEntry; 32 * 32],
}
#[derive(Debug, Clone, Copy, Default)]
@ -330,7 +330,7 @@ impl RegularScreenblockEntry {
}
pub fn set_palbank_index(&amp;mut self, palbank_index: u16) {
self.0 &amp;= 0b1111_1111_1111;
self.0 |= palbank_index;
self.0 |= palbank_index &lt;&lt; 12;
}
}
#}</code></pre></pre>

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html" class="active"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html" class="active"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -193,6 +193,33 @@ or 8bpp. From this we can determine that there's 512 tile slots in each of the
two object charblocks. However, in video modes 3, 4, and 5 the space for the
background cuts into the lower charblock, so you can only safely use the upper
charblock.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
pub fn obj_tile_4bpp(tile_index: usize) -&gt; Tile4bpp {
assert!(tile_index &lt; 512);
let address = VRAM + size_of::&lt;Charblock4bpp&gt;() * 4 + 32 * tile_index;
unsafe { VolatilePtr(address as *mut Tile4bpp).read() }
}
pub fn set_obj_tile_4bpp(tile_index: usize, tile: Tile4bpp) {
assert!(tile_index &lt; 512);
let address = VRAM + size_of::&lt;Charblock4bpp&gt;() * 4 + 32 * tile_index;
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
}
pub fn obj_tile_8bpp(tile_index: usize) -&gt; Tile8bpp {
assert!(tile_index &lt; 512);
let address = VRAM + size_of::&lt;Charblock8bpp&gt;() * 4 + 32 * tile_index;
unsafe { VolatilePtr(address as *mut Tile8bpp).read() }
}
pub fn set_obj_tile_8bpp(tile_index: usize, tile: Tile8bpp) {
assert!(tile_index &lt; 512);
let address = VRAM + size_of::&lt;Charblock8bpp&gt;() * 4 + 32 * tile_index;
unsafe { VolatilePtr(address as *mut Tile8bpp).write(tile) }
}
#}</code></pre></pre>
<p>With backgrounds you picked every single tile individually with a bunch of
screen entry values. Objects don't do that at all. Instead you pick a base tile,
size, and shape, then it figures out the rest from there. However, you may
@ -217,14 +244,14 @@ everything all lined up and into place anyway.</p>
<a class="header" href="#set-the-object-attributes" id="set-the-object-attributes"><h2>Set the Object Attributes</h2></a>
<p>The final step is to assign the correct attributes to an object. Each object has
three <code>u16</code> values that make up its overall attributes.</p>
<p>Before we go into the details, I want to remind you that the hardware will
attempt to process every single object every single frame, and also that all of
the GBA's memory is cleared to 0 at startup. Why do these two things matter
right now? As you'll see in a second an &quot;all zero&quot; set of object attributes
causes an 8x8 object to appear at 0,0 using object tile index 0. This is usually
<em>not</em> what you want your unused objects to do. When your game first starts you
should take a moment to mark any objects you won't be using as objects to not
render.</p>
<p>Before we go into the details, I want to bring up that the hardware will attempt
to process every single object every single frame if the object layer is
enabled, and also that all of the GBA's object memory is cleared to 0 at
startup. Why do these two things matter right now? As you'll see in a second an
&quot;all zero&quot; set of object attributes causes an 8x8 object to appear at 0,0 using
object tile index 0. This is usually <em>not</em> what you want your unused objects to
do. When your game first starts you should take a moment to mark any objects you
won't be using as objects to not render.</p>
<a class="header" href="#objectattributesattr0" id="objectattributesattr0"><h3>ObjectAttributes.attr0</h3></a>
<ul>
<li>8 bits for row coordinate (marks the top of the sprite)</li>
@ -518,7 +545,7 @@ impl ObjectAttributes {
<a rel="next" href="../ch03/gba_rng.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next" href="../ch03/gba_prng.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@ -536,7 +563,7 @@ impl ObjectAttributes {
<a href="../ch03/gba_rng.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a href="../ch03/gba_prng.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html" class="active"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html" class="active"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -161,13 +161,13 @@ and the index just directly picks which of the 256 colors is used.</li>
#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct Tile4bpp {
data: [u32; 8]
pub data: [u32; 8]
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct Tile8bpp {
data: [u32; 16]
pub data: [u32; 16]
}
#}</code></pre></pre>
<p>I hope this makes sense so far. At 4bpp, we have 4 bits per pixel, times 8
@ -196,13 +196,13 @@ tiles, and with 8bpp there's 256 tiles. So they'd be something like this:</p>
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct Charblock4bpp {
data: [Tile4bpp; 512],
pub data: [Tile4bpp; 512],
}
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct Charblock8bpp {
data: [Tile8bpp; 256],
pub data: [Tile8bpp; 256],
}
#}</code></pre></pre>
<p>You'll note that we can't even derive <code>Debug</code> or <code>Default</code> any more because the

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -183,6 +183,10 @@ for C, but it's what I based the ordering of this book's sections on.</li>
<li><a href="http://problemkaputt.de/gbatek.htm">GBATEK</a>, a homebrew tech manual for
GBA/NDS/DSi. We will regularly link to parts of it when talking about various
bits of the GBA.</li>
<li><a href="https://www.youtube.com/watch?v=t99L3JHhLc0">Getting Something for Nothing</a>
by James Munns. RustConf 2018. It specifically talks about zero cost
abstraction within an embedded rust context, which is exactly what we're all
about.</li>
</ul>
</main>

View file

@ -72,7 +72,7 @@
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<ol class="chapter"><li><a href="introduction.html" class="active"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
<ol class="chapter"><li><a href="introduction.html" class="active"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -183,6 +183,10 @@ for C, but it's what I based the ordering of this book's sections on.</li>
<li><a href="http://problemkaputt.de/gbatek.htm">GBATEK</a>, a homebrew tech manual for
GBA/NDS/DSi. We will regularly link to parts of it when talking about various
bits of the GBA.</li>
<li><a href="https://www.youtube.com/watch?v=t99L3JHhLc0">Getting Something for Nothing</a>
by James Munns. RustConf 2018. It specifically talks about zero cost
abstraction within an embedded rust context, which is exactly what we're all
about.</li>
</ul>
</main>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,9 +1,6 @@
#![feature(start)]
#![feature(asm)]
#![no_std]
use core::mem::size_of;
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
@ -11,19 +8,27 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
unsafe {
init_palette();
init_background();
clear_objects_starting_with(13);
arrange_cards();
init_selector();
loop {
// TODO the game
}
// bg palette
set_bg_palette_4bpp(0, 1, WHITE);
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
set_bg_palette_4bpp(0, 3, DARK_GRAY);
// bg tiles
set_bg_tile_4bpp(0, 0, ALL_TWOS);
set_bg_tile_4bpp(0, 1, ALL_THREES);
// screenblock
let light_entry = RegularScreenblockEntry::from_tile_id(0);
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
checker_screenblock(8, light_entry, dark_entry);
// bg0 control
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
// Display Control
unsafe { DISPCNT.write(DisplayControlSetting::JUST_ENABLE_BG0) };
loop {
// TODO the whole thing
}
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct VolatilePtr<T>(pub *mut T);
impl<T> VolatilePtr<T> {
@ -33,129 +38,54 @@ impl<T> VolatilePtr<T> {
pub unsafe fn write(&self, data: T) {
core::ptr::write_volatile(self.0, data);
}
pub unsafe fn offset(self, count: isize) -> Self {
pub fn offset(self, count: isize) -> Self {
VolatilePtr(self.0.wrapping_offset(count))
}
pub fn cast<Z>(self) -> VolatilePtr<Z> {
VolatilePtr(self.0 as *mut Z)
}
}
pub const DISPCNT: VolatilePtr<u16> = VolatilePtr(0x04000000 as *mut u16);
pub const MODE3: u16 = 3;
pub const BG2: u16 = 0b100_0000_0000;
pub const BACKGROUND_PALETTE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16);
pub const VRAM: usize = 0x600_0000;
pub const SCREEN_WIDTH: isize = 240;
pub const SCREEN_HEIGHT: isize = 160;
pub fn set_bg_palette_4bpp(palbank: usize, slot: usize, color: u16) {
assert!(palbank < 16);
assert!(slot > 0 && slot < 16);
unsafe {
BACKGROUND_PALETTE
.cast::<[u16; 16]>()
.offset(palbank as isize)
.cast::<u16>()
.offset(slot as isize)
.write(color);
}
}
pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
blue << 10 | green << 5 | red
}
pub unsafe fn mode3_clear_screen(color: u16) {
let color = color as u32;
let bulk_color = color << 16 | color;
let mut ptr = VolatilePtr(VRAM as *mut u32);
for _ in 0..SCREEN_HEIGHT {
for _ in 0..(SCREEN_WIDTH / 2) {
ptr.write(bulk_color);
ptr = ptr.offset(1);
}
}
}
pub const WHITE: u16 = rgb16(31, 31, 31);
pub const LIGHT_GRAY: u16 = rgb16(25, 25, 25);
pub const DARK_GRAY: u16 = rgb16(15, 15, 15);
pub unsafe fn mode3_draw_pixel(col: isize, row: isize, color: u16) {
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write(color);
}
pub unsafe fn mode3_read_pixel(col: isize, row: isize) -> u16 {
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).read()
}
pub const KEYINPUT: VolatilePtr<u16> = VolatilePtr(0x400_0130 as *mut u16);
/// A newtype over the key input state of the GBA.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct KeyInputSetting(u16);
/// A "tribool" value helps us interpret the arrow pad.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(i32)]
pub enum TriBool {
Minus = -1,
Neutral = 0,
Plus = 1,
}
pub fn key_input() -> KeyInputSetting {
unsafe { KeyInputSetting(KEYINPUT.read() ^ 0b0000_0011_1111_1111) }
}
pub const KEY_A: u16 = 1 << 0;
pub const KEY_B: u16 = 1 << 1;
pub const KEY_SELECT: u16 = 1 << 2;
pub const KEY_START: u16 = 1 << 3;
pub const KEY_RIGHT: u16 = 1 << 4;
pub const KEY_LEFT: u16 = 1 << 5;
pub const KEY_UP: u16 = 1 << 6;
pub const KEY_DOWN: u16 = 1 << 7;
pub const KEY_R: u16 = 1 << 8;
pub const KEY_L: u16 = 1 << 9;
impl KeyInputSetting {
pub fn contains(&self, key: u16) -> bool {
(self.0 & key) != 0
}
pub fn difference(&self, other: KeyInputSetting) -> KeyInputSetting {
KeyInputSetting(self.0 ^ other.0)
}
pub fn column_direction(&self) -> TriBool {
if self.contains(KEY_RIGHT) {
TriBool::Plus
} else if self.contains(KEY_LEFT) {
TriBool::Minus
} else {
TriBool::Neutral
}
}
pub fn row_direction(&self) -> TriBool {
if self.contains(KEY_DOWN) {
TriBool::Plus
} else if self.contains(KEY_UP) {
TriBool::Minus
} else {
TriBool::Neutral
}
}
}
pub const VCOUNT: VolatilePtr<u16> = VolatilePtr(0x0400_0006 as *mut u16);
pub fn vcount() -> u16 {
unsafe { VCOUNT.read() }
}
pub fn wait_until_vblank() {
while vcount() < SCREEN_HEIGHT as u16 {}
}
pub fn wait_until_vdraw() {
while vcount() >= SCREEN_HEIGHT as u16 {}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct Tile4bpp {
pub data: [u32; 8],
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct Tile8bpp {
pub data: [u32; 16],
}
pub const ALL_TWOS: Tile4bpp = Tile4bpp {
data: [
0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222,
],
};
pub const ALL_THREES: Tile4bpp = Tile4bpp {
data: [
0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333,
],
};
#[derive(Clone, Copy)]
#[repr(transparent)]
@ -163,630 +93,62 @@ pub struct Charblock4bpp {
pub data: [Tile4bpp; 512],
}
#[derive(Clone, Copy)]
pub const VRAM: VolatilePtr<Charblock4bpp> = VolatilePtr(0x0600_0000 as *mut Charblock4bpp);
pub fn set_bg_tile_4bpp(charblock: usize, index: usize, tile: Tile4bpp) {
assert!(charblock < 4);
assert!(index < 512);
unsafe { VRAM.offset(charblock as isize).cast::<Tile4bpp>().offset(index as isize).write(tile) }
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(transparent)]
pub struct Charblock8bpp {
pub data: [Tile8bpp; 256],
}
pub struct RegularScreenblockEntry(u16);
pub const PALRAM_BG_BASE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16);
pub fn bg_palette(slot: usize) -> u16 {
assert!(slot < 256);
unsafe { PALRAM_BG_BASE.offset(slot as isize).read() }
}
pub fn set_bg_palette(slot: usize, color: u16) {
assert!(slot < 256);
unsafe { PALRAM_BG_BASE.offset(slot as isize).write(color) }
}
pub unsafe fn init_palette() {
// palbank 0: black/white/gray
set_bg_palette(2, rgb16(31, 31, 31));
set_bg_palette(3, rgb16(15, 15, 15));
// palbank 1 is reds
set_bg_palette(1 * 16 + 1, rgb16(31, 0, 0));
set_bg_palette(1 * 16 + 2, rgb16(22, 0, 0));
set_bg_palette(1 * 16 + 3, rgb16(10, 0, 0));
// palbank 2 is greens
set_bg_palette(2 * 16 + 1, rgb16(0, 31, 0));
set_bg_palette(2 * 16 + 2, rgb16(0, 22, 0));
set_bg_palette(2 * 16 + 3, rgb16(0, 10, 0));
// palbank 2 is blues
set_bg_palette(3 * 16 + 1, rgb16(0, 0, 31));
set_bg_palette(3 * 16 + 2, rgb16(0, 0, 22));
set_bg_palette(3 * 16 + 3, rgb16(0, 0, 10));
// Direct copy all BG selections into OBJ palette too
let mut bgp = PALRAM_BG_BASE;
let mut objp = PALRAM_OBJECT_BASE;
for _ in 0..(4 * 16) {
objp.write(bgp.read());
bgp = bgp.offset(1);
objp = objp.offset(1);
impl RegularScreenblockEntry {
pub const SCREENBLOCK_ENTRY_TILE_ID_MASK: u16 = 0b11_1111_1111;
pub fn from_tile_id(id: u16) -> Self {
RegularScreenblockEntry(id & Self::SCREENBLOCK_ENTRY_TILE_ID_MASK)
}
}
pub fn bg_tile_4bpp(base_block: usize, tile_index: usize) -> Tile4bpp {
assert!(base_block < 4);
assert!(tile_index < 512);
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
unsafe { VolatilePtr(address as *mut Tile4bpp).read() }
}
pub fn set_bg_tile_4bpp(base_block: usize, tile_index: usize, tile: Tile4bpp) {
assert!(base_block < 4);
assert!(tile_index < 512);
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
}
pub fn bg_tile_8bpp(base_block: usize, tile_index: usize) -> Tile8bpp {
assert!(base_block < 4);
assert!(tile_index < 256);
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
unsafe { VolatilePtr(address as *mut Tile8bpp).read() }
}
pub fn set_bg_tile_8bpp(base_block: usize, tile_index: usize, tile: Tile8bpp) {
assert!(base_block < 4);
assert!(tile_index < 256);
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
unsafe { VolatilePtr(address as *mut Tile8bpp).write(tile) }
}
//
pub fn obj_tile_4bpp(tile_index: usize) -> Tile4bpp {
assert!(tile_index < 512);
let address = VRAM + size_of::<Charblock4bpp>() * 4 + 32 * tile_index;
unsafe { VolatilePtr(address as *mut Tile4bpp).read() }
}
pub fn set_obj_tile_4bpp(tile_index: usize, tile: Tile4bpp) {
assert!(tile_index < 512);
let address = VRAM + size_of::<Charblock4bpp>() * 4 + 32 * tile_index;
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
}
pub fn obj_tile_8bpp(tile_index: usize) -> Tile8bpp {
assert!(tile_index < 512);
let address = VRAM + size_of::<Charblock8bpp>() * 4 + 32 * tile_index;
unsafe { VolatilePtr(address as *mut Tile8bpp).read() }
}
pub fn set_obj_tile_8bpp(tile_index: usize, tile: Tile8bpp) {
assert!(tile_index < 512);
let address = VRAM + size_of::<Charblock8bpp>() * 4 + 32 * tile_index;
unsafe { VolatilePtr(address as *mut Tile8bpp).write(tile) }
}
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct RegularScreenblock {
data: [RegularScreenblockEntry; 32 * 32],
pub data: [RegularScreenblockEntry; 32 * 32],
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub fn checker_screenblock(slot: usize, a_entry: RegularScreenblockEntry, b_entry: RegularScreenblockEntry) {
let mut p = VRAM.cast::<RegularScreenblock>().offset(slot as isize).cast::<RegularScreenblockEntry>();
let mut checker = true;
for _row in 0..32 {
for _col in 0..32 {
unsafe { p.write(if checker { a_entry } else { b_entry }) };
p = p.offset(1);
checker = !checker;
}
checker = !checker;
}
}
#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct RegularScreenblockEntry(u16);
pub struct BackgroundControlSetting(u16);
impl RegularScreenblockEntry {
pub fn tile_id(self) -> u16 {
self.0 & 0b11_1111_1111
}
pub fn set_tile_id(&mut self, id: u16) {
self.0 &= !0b11_1111_1111;
self.0 |= id;
}
pub fn horizontal_flip(self) -> bool {
(self.0 & (1 << 0xA)) > 0
}
pub fn set_horizontal_flip(&mut self, bit: bool) {
if bit {
self.0 |= 1 << 0xA;
} else {
self.0 &= !(1 << 0xA);
}
}
pub fn vertical_flip(self) -> bool {
(self.0 & (1 << 0xB)) > 0
}
pub fn set_vertical_flip(&mut self, bit: bool) {
if bit {
self.0 |= 1 << 0xB;
} else {
self.0 &= !(1 << 0xB);
}
}
pub fn palbank_index(self) -> u16 {
self.0 >> 12
}
pub fn set_palbank_index(&mut self, palbank_index: u16) {
self.0 &= 0b1111_1111_1111;
self.0 |= palbank_index << 12;
impl BackgroundControlSetting {
pub fn from_base_block(sbb: u16) -> Self {
BackgroundControlSetting(sbb << 8)
}
}
pub const PALRAM_OBJECT_BASE: VolatilePtr<u16> = VolatilePtr(0x500_0200 as *mut u16);
pub const BG0CNT: VolatilePtr<BackgroundControlSetting> = VolatilePtr(0x400_0008 as *mut BackgroundControlSetting);
pub fn object_palette(slot: usize) -> u16 {
assert!(slot < 256);
unsafe { PALRAM_OBJECT_BASE.offset(slot as isize).read() }
}
pub fn set_object_palette(slot: usize, color: u16) {
assert!(slot < 256);
unsafe { PALRAM_OBJECT_BASE.offset(slot as isize).write(color) }
}
pub const OAM: usize = 0x700_0000;
pub fn object_attributes(slot: usize) -> ObjectAttributes {
assert!(slot < 128);
let ptr = VolatilePtr((OAM + slot * (size_of::<u16>() * 4)) as *mut u16);
unsafe {
ObjectAttributes {
attr0: ptr.read(),
attr1: ptr.offset(1).read(),
attr2: ptr.offset(2).read(),
}
}
}
pub fn set_object_attributes(slot: usize, obj: ObjectAttributes) {
assert!(slot < 128);
let ptr = VolatilePtr((OAM + slot * (size_of::<u16>() * 4)) as *mut u16);
unsafe {
ptr.write(obj.attr0);
ptr.offset(1).write(obj.attr1);
ptr.offset(2).write(obj.attr2);
}
}
pub fn clear_objects_starting_with(base_slot: usize) {
let mut obj = ObjectAttributes::default();
obj.set_rendering(ObjectRenderMode::Disabled);
for s in base_slot..128 {
set_object_attributes(s, obj);
}
}
pub fn position_of_card(card_col: usize, card_row: usize) -> (u16, u16) {
(10 + card_col as u16 * 17, 5 + card_row as u16 * 15)
}
pub fn arrange_cards() {
set_obj_tile_4bpp(1, FULL_ONE);
set_obj_tile_4bpp(2, FULL_TWO);
set_obj_tile_4bpp(3, FULL_THREE);
let mut obj = ObjectAttributes::default();
obj.set_tile_index(2); // along with palbank0, this is a white card
for card_row in 0..3 {
for card_col in 0..4 {
let (col, row) = position_of_card(card_col, card_row);
obj.set_column(col);
obj.set_row(row);
set_object_attributes(1 + card_col as usize + (card_row as usize * 3), obj);
}
}
}
pub fn init_selector() {
set_obj_tile_4bpp(0, CARD_SELECTOR);
let mut obj = ObjectAttributes::default();
let (col, row) = position_of_card(0, 0);
obj.set_column(col);
obj.set_row(row);
set_object_attributes(0, obj);
}
/// BG2 Control
pub const BG2CNT: VolatilePtr<u16> = VolatilePtr(0x400_000C as *mut u16);
pub unsafe fn init_background() {
// put the bg tiles in charblock 0
set_bg_tile_4bpp(0, 0, FULL_ONE);
set_bg_tile_4bpp(0, 1, FULL_THREE);
// make a checker pattern, place at screenblock 8 (aka the start of charblock 1)
let entry_black = RegularScreenblockEntry::default();
let mut entry_gray = RegularScreenblockEntry::default();
entry_gray.set_tile_id(1);
let mut using_black = true;
let mut screenblock: RegularScreenblock = core::mem::zeroed();
for entry_mut in screenblock.data.iter_mut() {
*entry_mut = if using_black { entry_black } else { entry_gray };
using_black = !using_black;
}
let p: VolatilePtr<RegularScreenblock> = VolatilePtr((VRAM + size_of::<Charblock8bpp>()) as *mut RegularScreenblock);
p.write(screenblock);
// turn on bg2 and configure it
let display_control_value = DISPCNT.read();
DISPCNT.write(display_control_value | BG2);
const SCREEN_BASE_BLOCK_FIRST_BIT: u32 = 8;
BG2CNT.write(8 << SCREEN_BASE_BLOCK_FIRST_BIT);
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct ObjectAttributes {
attr0: u16,
attr1: u16,
attr2: u16,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ObjectRenderMode {
Normal,
Affine,
Disabled,
DoubleAreaAffine,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ObjectMode {
Normal,
AlphaBlending,
ObjectWindow,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ObjectShape {
Square,
Horizontal,
Vertical,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ObjectOrientation {
Normal,
HFlip,
VFlip,
BothFlip,
Affine(u8),
}
impl ObjectAttributes {
pub fn row(&self) -> u16 {
self.attr0 & 0b1111_1111
}
pub fn column(&self) -> u16 {
self.attr1 & 0b1_1111_1111
}
pub fn rendering(&self) -> ObjectRenderMode {
match (self.attr0 >> 8) & 0b11 {
0 => ObjectRenderMode::Normal,
1 => ObjectRenderMode::Affine,
2 => ObjectRenderMode::Disabled,
3 => ObjectRenderMode::DoubleAreaAffine,
_ => unimplemented!(),
}
}
pub fn mode(&self) -> ObjectMode {
match (self.attr0 >> 0xA) & 0b11 {
0 => ObjectMode::Normal,
1 => ObjectMode::AlphaBlending,
2 => ObjectMode::ObjectWindow,
_ => unimplemented!(),
}
}
pub fn mosaic(&self) -> bool {
((self.attr0 << 3) as i16) < 0
}
pub fn two_fifty_six_colors(&self) -> bool {
((self.attr0 << 2) as i16) < 0
}
pub fn shape(&self) -> ObjectShape {
match (self.attr0 >> 0xE) & 0b11 {
0 => ObjectShape::Square,
1 => ObjectShape::Horizontal,
2 => ObjectShape::Vertical,
_ => unimplemented!(),
}
}
pub fn orientation(&self) -> ObjectOrientation {
if (self.attr0 >> 8) & 1 > 0 {
ObjectOrientation::Affine((self.attr1 >> 9) as u8 & 0b1_1111)
} else {
match (self.attr1 >> 0xC) & 0b11 {
0 => ObjectOrientation::Normal,
1 => ObjectOrientation::HFlip,
2 => ObjectOrientation::VFlip,
3 => ObjectOrientation::BothFlip,
_ => unimplemented!(),
}
}
}
pub fn size(&self) -> u16 {
self.attr1 >> 0xE
}
pub fn tile_index(&self) -> u16 {
self.attr2 & 0b11_1111_1111
}
pub fn priority(&self) -> u16 {
self.attr2 >> 0xA
}
pub fn palbank(&self) -> u16 {
self.attr2 >> 0xC
}
//
pub fn set_row(&mut self, row: u16) {
self.attr0 &= !0b1111_1111;
self.attr0 |= row & 0b1111_1111;
}
pub fn set_column(&mut self, col: u16) {
self.attr1 &= !0b1_1111_1111;
self.attr2 |= col & 0b1_1111_1111;
}
pub fn set_rendering(&mut self, rendering: ObjectRenderMode) {
const RENDERING_MASK: u16 = 0b11 << 8;
self.attr0 &= !RENDERING_MASK;
self.attr0 |= (rendering as u16) << 8;
}
pub fn set_mode(&mut self, mode: ObjectMode) {
const MODE_MASK: u16 = 0b11 << 0xA;
self.attr0 &= MODE_MASK;
self.attr0 |= (mode as u16) << 0xA;
}
pub fn set_mosaic(&mut self, bit: bool) {
const MOSAIC_BIT: u16 = 1 << 0xC;
if bit {
self.attr0 |= MOSAIC_BIT
} else {
self.attr0 &= !MOSAIC_BIT
}
}
pub fn set_two_fifty_six_colors(&mut self, bit: bool) {
const COLOR_MODE_BIT: u16 = 1 << 0xD;
if bit {
self.attr0 |= COLOR_MODE_BIT
} else {
self.attr0 &= !COLOR_MODE_BIT
}
}
pub fn set_shape(&mut self, shape: ObjectShape) {
self.attr0 &= 0b0011_1111_1111_1111;
self.attr0 |= (shape as u16) << 0xE;
}
pub fn set_orientation(&mut self, orientation: ObjectOrientation) {
const AFFINE_INDEX_MASK: u16 = 0b1_1111 << 9;
self.attr1 &= !AFFINE_INDEX_MASK;
let bits = match orientation {
ObjectOrientation::Affine(index) => (index as u16) << 9,
ObjectOrientation::Normal => 0,
ObjectOrientation::HFlip => 1 << 0xC,
ObjectOrientation::VFlip => 1 << 0xD,
ObjectOrientation::BothFlip => 0b11 << 0xC,
};
self.attr1 |= bits;
}
pub fn set_size(&mut self, size: u16) {
self.attr1 &= 0b0011_1111_1111_1111;
self.attr1 |= size << 14;
}
pub fn set_tile_index(&mut self, index: u16) {
self.attr2 &= !0b11_1111_1111;
self.attr2 |= 0b11_1111_1111 & index;
}
pub fn set_priority(&mut self, priority: u16) {
self.attr2 &= !0b0000_1100_0000_0000;
self.attr2 |= (priority & 0b11) << 0xA;
}
pub fn set_palbank(&mut self, palbank: u16) {
self.attr2 &= !0b1111_0000_0000_0000;
self.attr2 |= (palbank & 0b1111) << 0xC;
}
}
pub fn div_modulus(numerator: i32, denominator: i32) -> (i32, i32) {
assert!(denominator != 0);
{
let div_out: i32;
let mod_out: i32;
unsafe {
asm!(/* assembly template */ "swi 0x06"
:/* output operands */ "={r0}"(div_out), "={r1}"(mod_out)
:/* input operands */ "{r0}"(numerator), "{r1}"(denominator)
:/* clobbers */ "r3"
:/* options */
);
}
(div_out, mod_out)
}
}
pub fn div(numerator: i32, denominator: i32) -> i32 {
div_modulus(numerator, denominator).0
}
pub fn modulus(numerator: i32, denominator: i32) -> i32 {
div_modulus(numerator, denominator).1
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RandRangeU16 {
range: u16,
threshold: u16,
}
impl RandRangeU16 {
pub fn new(mut range: u16) -> Self {
let mut threshold = range.wrapping_neg();
if threshold >= range {
threshold -= range;
if threshold >= range {
threshold = modulus(threshold as i32, range as i32) as u16;
}
}
RandRangeU16 { range, threshold }
}
pub fn roll_random(&self, rng: &mut impl FnMut() -> u16) -> u16 {
let mut x: u16 = rng();
let mut m: u32 = x as u32 * self.range as u32;
let mut l: u16 = m as u16;
if l < self.range {
while l < self.threshold {
x = rng();
m = x as u32 * self.range as u32;
l = m as u16;
}
}
(m >> 16) as u16
}
}
pub fn bounded_rand32(rng: &mut impl FnMut() -> u32, mut range: u32) -> u32 {
let mut mask: u32 = !0;
range -= 1;
mask >>= (range | 1).leading_zeros();
let mut x = rng() & mask;
while x > range {
x = rng() & mask;
}
x
}
pub const TM0D: VolatilePtr<u16> = VolatilePtr(0x400_0100 as *mut u16);
pub const TM0CNT: VolatilePtr<u16> = VolatilePtr(0x400_0102 as *mut u16);
pub const TM1D: VolatilePtr<u16> = VolatilePtr(0x400_0104 as *mut u16);
pub const TM1CNT: VolatilePtr<u16> = VolatilePtr(0x400_0106 as *mut u16);
pub const TM2D: VolatilePtr<u16> = VolatilePtr(0x400_0108 as *mut u16);
pub const TM2CNT: VolatilePtr<u16> = VolatilePtr(0x400_010A as *mut u16);
pub const TM3D: VolatilePtr<u16> = VolatilePtr(0x400_010C as *mut u16);
pub const TM3CNT: VolatilePtr<u16> = VolatilePtr(0x400_010E as *mut u16);
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct TimerControl(u16);
pub struct DisplayControlSetting(u16);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TimerFrequency {
One = 0,
SixFour = 1,
TwoFiveSix = 2,
OneZeroTwoFour = 3,
impl DisplayControlSetting {
pub const JUST_ENABLE_BG0: DisplayControlSetting = DisplayControlSetting(1 << 8);
}
impl TimerControl {
pub fn frequency(self) -> TimerFrequency {
match self.0 & 0b11 {
0 => TimerFrequency::One,
1 => TimerFrequency::SixFour,
2 => TimerFrequency::TwoFiveSix,
3 => TimerFrequency::OneZeroTwoFour,
_ => unreachable!(),
}
}
pub fn cascading(self) -> bool {
self.0 & 0b100 > 0
}
pub fn interrupt(self) -> bool {
self.0 & 0b100_0000 > 0
}
pub fn enabled(self) -> bool {
self.0 & 0b1000_0000 > 0
}
//
pub fn set_frequency(&mut self, frequency: TimerFrequency) {
self.0 &= !0b11;
self.0 |= frequency as u16;
}
pub fn set_cascading(&mut self, bit: bool) {
if bit {
self.0 |= 0b100;
} else {
self.0 &= !0b100;
}
}
pub fn set_interrupt(&mut self, bit: bool) {
if bit {
self.0 |= 0b100_0000;
} else {
self.0 &= !0b100_0000;
}
}
pub fn set_enabled(&mut self, bit: bool) {
if bit {
self.0 |= 0b1000_0000;
} else {
self.0 &= !0b1000_0000;
}
}
}
/// Mucks with the settings of Timers 0 and 1.
unsafe fn u32_from_user_wait() -> u32 {
let mut t = TimerControl::default();
t.set_enabled(true);
t.set_cascading(true);
TM1CNT.write(t.0);
t.set_cascading(false);
TM0CNT.write(t.0);
while key_input().0 == 0 {}
t.set_enabled(false);
TM0CNT.write(t.0);
TM1CNT.write(t.0);
let low = TM0D.read() as u32;
let high = TM1D.read() as u32;
(high << 32) | low
}
/// For the user's "cursor" to select a card
#[rustfmt::skip]
pub const CARD_SELECTOR: Tile4bpp = Tile4bpp {
data : [
0x11100111,
0x11000011,
0x10000001,
0x00000000,
0x00000000,
0x10000001,
0x11000011,
0x11100111
]
};
#[rustfmt::skip]
pub const FULL_ONE: Tile4bpp = Tile4bpp {
data : [
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
]
};
#[rustfmt::skip]
pub const FULL_TWO: Tile4bpp = Tile4bpp {
data : [
0x22222222,
0x22222222,
0x22222222,
0x22222222,
0x22222222,
0x22222222,
0x22222222,
0x22222222
]
};
#[rustfmt::skip]
pub const FULL_THREE: Tile4bpp = Tile4bpp {
data : [
0x33333333,
0x33333333,
0x33333333,
0x33333333,
0x33333333,
0x33333333,
0x33333333,
0x33333333
]
};
pub const DISPCNT: VolatilePtr<DisplayControlSetting> = VolatilePtr(0x0400_0000 as *mut DisplayControlSetting);