edits, cleanups, and a goal for ch3

This commit is contained in:
Lokathor 2018-11-17 17:14:42 -07:00
parent 3a355db578
commit 241fb1746c
38 changed files with 697 additions and 344 deletions

View file

@ -14,7 +14,7 @@ before_script:
script:
- cargo check && cargo check --release
# exclude the examples from the test build, just the lib
# Only run a test build for the library itself
- cargo test --lib && cargo test --lib --release
- cd book && mdbook build

View file

@ -16,12 +16,12 @@ dependencies = ["create-target-dir"]
command = "arm-none-eabi-as"
args = ["crt0.s", "-o", "target/crt0.o"]
[tasks.build-debug]
[tasks.build-examples-debug]
dependencies = ["assemble"]
command = "cargo"
args = ["xbuild", "--examples", "--target", "thumbv4-none-agb.json"]
[tasks.build-release]
[tasks.build-examples-release]
dependencies = ["assemble"]
command = "cargo"
args = ["xbuild", "--examples", "--target", "thumbv4-none-agb.json", "--release"]
@ -56,4 +56,8 @@ fn main() -> std::io::Result<()> {
]
[tasks.build]
dependencies = ["build-debug", "build-release", "pack-roms"]
dependencies = ["build-examples-debug", "build-examples-release", "pack-roms"]
[tasks.test]
command = "cargo"
args = ["test", "--lib"]

View file

@ -1,7 +1,6 @@
[book]
title = "Rust GBA Tutorials"
title = "Rust GBA Guide"
authors = ["Lokathor"]
#description = "Rust GBA Tutorials."
[build]
build-dir = "../docs"

View file

@ -5,6 +5,7 @@
* [Ch 0: Development Setup](ch00/index.md)
* [Ch 1: Hello GBA](ch01/index.md)
* [hello1](ch01/hello1.md)
* [Volatile](ch01/volatile.md)
* [IO Registers](ch01/io_registers.md)
* [The Display Control Register](ch01/the_display_control_register.md)
* [Video Memory Intro](ch01/video_memory_intro.md)

View file

@ -4,26 +4,25 @@ Before you can build a GBA game you'll have to follow some special steps to
setup the development environment. Perhaps unfortunately, there's enough detail
here to warrant a mini-chapter all on its own.
Before we begin I'd like to give a special thanks to **Ketsuban**, who is the
wizard that arranged for all of this to be able to happen and laid out the
details of the plan to the rest of the world.
Once again, extra special thanks to **Ketsuban**, who first dove into how to
make this all work with rust and then shared it with the world.
## Per System Setup
Obviously you need your computer to have a working rust installation. However,
you'll also need to ensure that you're using a nightly toolchain. You can run
`rustup default nightly` to set nightly as the system wide default toolchain, or
you can use a [toolchain
Obviously you need your computer to have a [working rust
installation](https://rustup.rs/). However, you'll also need to ensure that
you're using a nightly toolchain. You can run `rustup default nightly` to set
nightly as the system wide default toolchain, or you can use a [toolchain
file](https://github.com/rust-lang-nursery/rustup.rs#the-toolchain-file) to use
nightly just on a specific project, but either way we'll be assuming nightly
from now on.
nightly just on a specific project, but either way we'll be assuming the use of
nightly from now on.
Next you need [devkitpro](https://devkitpro.org/wiki/Getting_Started). They've
Next, you need [devkitpro](https://devkitpro.org/wiki/Getting_Started). They've
got a graphical installer for Windows, and `pacman` support on Linux. We'll be
using a few of their binutils for the `arm-none-eabi` target, and we'll also be
using some of their tools that are specific to GBA development, so _even if_ you
already have the right binutils for whatever reason, you'll still want devkitpro
for the `gbafix` utility.
using a few of general their binutils for the `arm-none-eabi` target, and we'll
also be using some of their tools that are specific to GBA development, so _even
if_ you already have the right binutils for whatever reason, you'll still want
devkitpro for the `gbafix` utility.
* On Windows you'll want something like `C:\devkitpro\devkitARM\bin` and
`C:\devkitpro\tools\bin` to be [added to your
@ -37,21 +36,20 @@ cargo will figure it all out for you.
## Per Project Setup
Now you'll need some particular files each time you want to start a new project.
You can find them in the root of the [rust-console/gba
repo](https://github.com/rust-console/gba).
Once the system wide tools are ready, you'll need some particular files each
time you want to start a new project. You can find them in the root of the
[rust-console/gba repo](https://github.com/rust-console/gba).
* `thumbv4-none-agb.json` describes the overall GBA to cargo-xbuild so it knows
what to do. This is actually a somewhat made up target name since there's no
official target name. The GBA is essentially the same as a normal
`thumbv4-none-eabi` device, but we give it the "agb" signifier so that later
on we'll be able to use rust's `cfg` ability to allow our code to know if it's
specifically targeting a GBA or some other similar device (like an NDS).
* `thumbv4-none-agb.json` describes the overall GBA to cargo-xbuild (and LLVM)
so it knows what to do. Technically the GBA is `thumbv4-none-eabi`, but we
change the `eabi` to `agb` so that we can distinguish it from other `eabi`
devices when using `cfg` flags.
* `crt0.s` describes some ASM startup stuff. If you have more ASM to place here
later on this is where you can put it. You also need to build it into a
`crt0.o` file before it can actually be used, but we'll cover that below.
* `linker.ld` tells the linker more critical info about the layout expectations
that the GBA has about our program.
* `linker.ld` tells the linker all the critical info about the layout
expectations that the GBA has about our program, and that it should also
include the `crt0.o` file with our compiled rust code.
## Compiling
@ -72,13 +70,13 @@ Once you've got something to build, you perform the following steps:
as `--release`, and options, such as `--bin foo` or `--examples`, that you'd
expect `cargo` to accept.
* You **can not** build and run tests this way, because they require `std`,
which the GBA doesn't have. You can still run some of your project's tests
with `cargo test`, but that builds for your local machine, so anything
specific to the GBA (such as reading and writing registers) won't be
testable that way. If you want to isolate and try out some piece code
running on the GBA you'll unfortunately have to make a demo for it in your
`examples/` directory and then run the demo in an emulator and see if it
does what you expect.
which the GBA doesn't have. If you want you can still run some of your
project's tests with `cargo test --lib` or similar, but that builds for your
local machine, so anything specific to the GBA (such as reading and writing
registers) won't be testable that way. If you want to isolate and try out
some piece code running on the GBA you'll unfortunately have to make a demo
for it in your `examples/` directory and then run the demo in an emulator
and see if it does what you expect.
* The file extension is important. `cargo xbuild` takes it as a flag to
compile dependencies with the same sysroot, so you can include crates
normally. Well, creates that work in the GBA's limited environment, but you
@ -132,3 +130,6 @@ transfer to a flash cart there's a little more to do.
And you're finally done!
Of course, you probably want to make a script for all that, but it's up to you.
On our own project we have it mostly set up within a `Makefile.toml` which runs
using the [cargo-make](https://github.com/sagiegurari/cargo-make) plugin. It's
not really the best plugin, but it's what's available.

View file

@ -1,5 +1,6 @@
# hello1
Our first example will be a totally minimal, full magic number crazy town.
Ready? Here goes:
`hello1.rs`
@ -8,7 +9,6 @@ Ready? Here goes:
#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
@ -26,17 +26,18 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
}
```
Throw that into your project, build the program (as described back in Chapter
0), and give it a run. You should see a red, green, and blue dot close-ish to
the middle of the screen. If you don't, something already went wrong. Double
check things, phone a friend, write your senators, try asking Ketsuban on the
[Rust Community Discord](https://discordapp.com/invite/aVESxV8), until you're
able to get your three dots going.
Throw that into your project skeleton, build the program (as described back in
Chapter 0), and give it a run in your emulator. You should see a red, green, and
blue dot close-ish to the middle of the screen. If you don't, something already
went wrong. Double check things, phone a friend, write your senators, try asking
Ketsuban on the [Rust Community Discord](https://discordapp.com/invite/aVESxV8),
until you're able to get your three dots going.
## Explaining hello1
## A basic hello1 explanation
So, what just happened? Even if you're used to Rust that might look pretty
strange. We'll go over each part extra carefully.
strange. We'll go over most of the little parts right here, and then bigger
parts will get their own sections.
```rust
#![feature(start)]
@ -60,7 +61,6 @@ There's no standard library available on the GBA, so we'll have to live a core
only life.
```rust
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
@ -74,10 +74,6 @@ However, right now we don't know how to get any sort of message out to the user
so... we do nothing at all. We _can't even return_ from here, so we just sit in
an infinite loop. The player will have to reset the universe from the outside.
The `#[cfg(not(test))]` part makes this item only exist in the program when
we're _not_ in a test build. This is so that `cargo test` and such work right as
much as possible.
```rust
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
@ -148,46 +144,5 @@ magic numbers mean or do.
* `0x06000000` is the start of Video RAM.
So we write some magic to the display control register once, then we write some
other magic to three locations of magic to the Video RAM. We get three dots,
each in their own location... so that second part makes sense at least.
We'll get into the magic number details in the other sections of this chapter.
## Sidebar: Volatile
We'll get into what all that is in a moment, but first let's ask ourselves: Why
are we doing _volatile_ writes? You've probably never used it before at all.
What is volatile anyway?
Well, the optimizer is pretty aggressive some of the time, and so it'll skip
reads and writes when it thinks can. Like if you write to a pointer once, and
then again a moment later, and it didn't see any other reads in between, it'll
think that it can just skip doing that first write since it'll get overwritten
anyway. Sometimes that's right, but sometimes it's wrong.
Marking a read or write as _volatile_ tells the compiler that it really must do
that action, and in the exact order that we wrote it out. It says that there
might even be special hardware side effects going on that the compiler isn't
aware of. In this case, the write to the display control register sets a video
mode, and the writes to the Video RAM set pixels that will show up on the
screen.
Similar to "atomic" operations you might have heard about, all volatile
operations are enforced to happen in the exact order that you specify them, but
only relative to other volatile operations. So something like
```rust
c.volatile_write(5);
a += b;
d.volatile_write(7);
```
might end up changing `a` either before or after the change to `c` (since the
value of `a` doesn't affect the write to `c`), but the write to `d` will
_always_ happen after the write to `c` even though the compiler doesn't see any
direct data dependency there.
If you ever use volatile stuff on other platforms it's important to note that
volatile doesn't make things thread-safe, you still need atomic for that.
However, the GBA doesn't have threads, so we don't have to worry about thread
safety concerns.
other magic to three magic locations in the Video RAM. Somehow that shows three
dots. Gotta read on to find out why!

View file

@ -8,7 +8,6 @@ Okay so let's have a look again:
#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
@ -28,10 +27,11 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
Now let's clean this up so that it's clearer what's going on.
First we'll label that display control stuff:
First we'll label that display control stuff, including using the `VolatilePtr`
type from the volatile explanation:
```rust
pub const DISPCNT: *mut u16 = 0x04000000 as *mut u16;
pub const DISPCNT: VolatilePtr<u16> = VolatilePtr(0x04000000 as *mut u16);
pub const MODE3: u16 = 3;
pub const BG2: u16 = 0b100_0000_0000;
```
@ -43,9 +43,12 @@ pub const VRAM: usize = 0x06000000;
pub const SCREEN_WIDTH: isize = 240;
```
And then we want a small helper function for putting together a color value.
Note that VRAM has to be interpreted in different ways depending on mode, so we
just leave it as `usize` and we'll cast it into the right form closer to the
actual use.
Happily, this one can even be declared as a const function. At the time of
Next we want a small helper function for putting together a color value.
Happily, this one can even be declared as a `const` function. At the time of
writing, we've got the "minimal const fn" support in nightly. It really is quite
limited, but I'm happy to let rustc and LLVM pre-compute as much as they can
when it comes to the GBA's tiny CPU.
@ -62,7 +65,7 @@ usually helps you think about it a lot better.
```rust
pub unsafe fn mode3_pixel(col: isize, row: isize, color: u16) {
(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write_volatile(color);
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write(color);
}
```
@ -74,7 +77,6 @@ So now we've got this:
#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
@ -83,7 +85,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
unsafe {
DISPCNT.write_volatile(MODE3 | BG2);
DISPCNT.write(MODE3 | BG2);
mode3_pixel(120, 80, rgb16(31, 0, 0));
mode3_pixel(136, 80, rgb16(0, 31, 0));
mode3_pixel(120, 96, rgb16(0, 0, 31));
@ -91,7 +93,22 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
}
}
pub const DISPCNT: *mut u16 = 0x04000000 as *mut u16;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[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 unsafe fn offset(self, count: isize) -> Self {
VolatilePtr(self.0.wrapping_offset(count))
}
}
pub const DISPCNT: VolatilePtr<u16> = VolatilePtr(0x04000000 as *mut u16);
pub const MODE3: u16 = 3;
pub const BG2: u16 = 0b100_0000_0000;
@ -103,7 +120,7 @@ pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
}
pub unsafe fn mode3_pixel(col: isize, row: isize, color: u16) {
(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write_volatile(color);
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write(color);
}
```

View file

@ -107,6 +107,3 @@ First let's [convert that to
binary](https://www.wolframalpha.com/input/?i=0x0403), and we get
`0b100_0000_0011`. So, that's setting Mode 3 with background 2 enabled and
nothing else special.
However, I think we can do better than that. This is a prime target for more
newtyping as we attempt a `hello2` program.

View file

@ -106,8 +106,8 @@ So at pixels `(120,80)`, `(136,80)`, and `(120,96)` we write three values. Once
again we probably need to [convert them](https://www.wolframalpha.com/) into
binary to make sense of it.
* 0x001F: 0b11111
* 0x03E0: 0b11111_00000
* 0x7C00: 0b11111_00000_00000
* 0x001F: 0b0_00000_00000_11111
* 0x03E0: 0b0_00000_11111_00000
* 0x7C00: 0b0_11111_00000_00000
Ah, of course, a red pixel, a green pixel, and a blue pixel.

70
book/src/ch01/volatile.md Normal file
View file

@ -0,0 +1,70 @@
# Volatile
Before we focus on what the numbers mean, first let's ask ourselves: Why are we
doing _volatile_ writes? You've probably never used that keywords before at all.
What _is_ volatile anyway?
Well, the optimizer is pretty aggressive, and so it'll skip reads and writes
when it thinks can. Like if you write to a pointer once, and then again a moment
later, and it didn't see any other reads in between, it'll think that it can
just skip doing that first write since it'll get overwritten anyway. Sometimes
that's correct, but sometimes it's not.
Marking a read or write as _volatile_ tells the compiler that it really must do
that action, and in the exact order that we wrote it out. It says that there
might even be special hardware side effects going on that the compiler isn't
aware of. In this case, the write to the display control register sets a video
mode, and the writes to the Video RAM set pixels that will show up on the
screen.
Similar to "atomic" operations you might have heard about, all volatile
operations are enforced to happen in the exact order that you specify them, but
only relative to other volatile operations. So something like
```rust
c.volatile_write(5);
a += b;
d.volatile_write(7);
```
might end up changing `a` either before or after the change to `c` (since the
value of `a` doesn't affect the write to `c`), but the write to `d` will
_always_ happen after the write to `c`, even though the compiler doesn't see any
direct data dependency there.
If you ever go on to use volatile stuff on other platforms it's important to
note that volatile doesn't make things thread-safe, you still need atomic for
that. However, the GBA doesn't have threads, so we don't have to worry about
those sorts of thread safety concerns (there's interrupts, but that's another
matter).
## Volatile by default
Of course, writing out `volatile_write` every time is more than we wanna do.
There's clarity and then there's excessive. This is a chance to write our first
[newtype](https://doc.rust-lang.org/1.0.0/style/features/types/newtype.html).
Basically a type that's got the exact same binary representation as some other
type, but new methods and trait implementations.
We want a `*mut T` that's volatile by default, and also when we offset it...
well the verdict is slightly unclear on how `offset` vs `wrapping_offset` work
when you're using pointers that you made up out of nowhere. I've asked the
experts and they genuinely weren't sure, so we'll make an `offset` method that
does a `wrapping_offset` just to be careful.
```rust
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[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 unsafe fn offset(self, count: isize) -> Self {
VolatilePtr(self.0.wrapping_offset(count))
}
}
```

View file

@ -16,21 +16,21 @@ We need some better drawing operations this time around.
pub unsafe fn mode3_clear_screen(color: u16) {
let color = color as u32;
let bulk_color = color << 16 | color;
let mut ptr = VRAM as *mut u32;
let mut ptr = VolatilePtr(VRAM as *mut u32);
for _ in 0..SCREEN_HEIGHT {
for _ in 0..(SCREEN_WIDTH / 2) {
ptr.write_volatile(bulk_color);
ptr.write(bulk_color);
ptr = ptr.offset(1);
}
}
}
pub unsafe fn mode3_draw_pixel(col: isize, row: isize, color: u16) {
(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write_volatile(color);
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write(color);
}
pub unsafe fn mode3_read_pixel(col: isize, row: isize) -> u16 {
(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).read_volatile()
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).read()
}
```
@ -46,7 +46,7 @@ Now we just have to fill in the main function:
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
unsafe {
DISPCNT.write_volatile(MODE3 | BG2);
DISPCNT.write(MODE3 | BG2);
}
let mut px = SCREEN_WIDTH / 2;
@ -55,7 +55,7 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
loop {
// read the input for this frame
let this_frame_keys = read_key_input();
let this_frame_keys = key_input();
// adjust game state and wait for vblank
px += 2 * this_frame_keys.column_direction() as isize;

View file

@ -56,15 +56,15 @@ a `u16` and then wrap that in our newtype which will implement methods for
reading and writing the key bits.
```rust
pub const KEYINPUT: *mut u16 = 0x400_0130 as *mut u16;
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);
pub fn read_key_input() -> KeyInputSetting {
unsafe { KeyInputSetting(KEYINPUT.read_volatile()) }
pub fn key_input() -> KeyInputSetting {
unsafe { KeyInputSetting(KEYINPUT.read()) }
}
```
@ -98,7 +98,7 @@ a mask for only the 10 used bits we can flip the "low when pressed" values so
that the entire result has active bits in all positions where a key is pressed.
```rust
pub fn read_key_input() -> KeyInputSetting {
pub fn key_input() -> KeyInputSetting {
unsafe { KeyInputSetting(KEYINPUT.read_volatile() ^ 0b0000_0011_1111_1111) }
}
```

View file

@ -46,10 +46,10 @@ quickly during the blank period.
So first we want a way to check the vcount value at all:
```rust
pub const VCOUNT: *mut u16 = 0x0400_0006 as *mut u16;
pub const VCOUNT: VolatilePtr<u16> = VolatilePtr(0x0400_0006 as *mut u16);
pub fn read_vcount() -> u16 {
unsafe { VCOUNT.read_volatile() }
pub fn vcount() -> u16 {
unsafe { VCOUNT.read() }
}
```
@ -59,11 +59,11 @@ Then we want two little helper functions to wait until VBlank and vdraw.
pub const SCREEN_HEIGHT: isize = 160;
pub fn wait_until_vblank() {
while read_vcount() < SCREEN_HEIGHT as u16 {}
while vcount() < SCREEN_HEIGHT as u16 {}
}
pub fn wait_until_vdraw() {
while read_vcount() >= SCREEN_HEIGHT as u16 {}
while vcount() >= SCREEN_HEIGHT as u16 {}
}
```

View file

@ -1 +1,17 @@
# Ch 3: Memory and Objects
Alright so we can do some basic "movement", but we left a big trail in the video
memory of where we went. Most of the time that's not what we want at all. If we
want to draw something over top of our background without trashing the
background memory that's an "object" (but not in the "Object Oriented" sense).
You might recall that objects have their own layer that you can enable in the
display control register.
Of course, once we're drawing these objects we'll want some scratch space to
work with them a bit, so we'll finally go over the GBA's full memory layout.
And since most games are pretty boring without an RNG, we'll cover the kinds of
RNG that you might want to include in a GBA game.
Then we'll do something or other that includes moving things and and RNG...
which is pretty much any game at all.

View file

@ -1,8 +1,38 @@
# Introduction
Here's a book that'll help you program in Rust on the GBA.
Here's a book that'll help you program in Rust on the Game Boy Advance (GBA).
It's very "work in progress". At the moment there's only one demo program.
It's a work in progress of course, but so is most of everything in Rust.
## Style and Purpose
I'm out to teach you how to program in Rust on the GBA, obviously. However,
while there _is_ a [gba](https://github.com/rust-console/gba) crate, and while I
genuinely believe it to be a good and useful crate for GBA programming, we _will
not_ be using the `gba` crate within this book. In fact we won't be using any
crates at all. We can call it the [Handmade Hero](https://handmadehero.org/)
approach, if you like.
I don't want to just teach you how to use the `gba` crate, I want to teach you
what you'd need to know to write the crate from scratch if it wasn't there.
Each chapter of the book will focus on a few things you'll need to know about
GBA programming and then present a fully self-contained example that puts those
ideas into action. Just one file per example, no dependencies, no external
assets, no fuss. The examples will be in the text of the book within code
blocks, but also you can find them in the [examples
directory](https://github.com/rust-console/gba/tree/master/examples) of the repo
if you want to get them that way.
## Expected Knowledge
I will try not to ask too much of the reader ahead of time, but you are expected
to have already read [The Rust Book](https://doc.rust-lang.org/book/).
It's very difficult to know when you've said something that someone else won't
already know about, or if you're presenting ideas out of order. If things aren't
clear please [file an issue](https://github.com/rust-console/gba/issues) and
we'll try to address it.
## Getting Help
@ -14,11 +44,12 @@ channel.
* `Lokathor` is the fool who decided to write a crate and book for it.
If it's _not_ a GBA specific question then you can probably ask any of the other
folks in the server as well.
folks in the server as well (there's a few hundred folks).
## Other Works
## Further Reading
If you want to read more about developing on the GBA there are some other good resources as well:
If you want to read more about developing on the GBA there are some other good
resources as well:
* [Tonc](https://www.coranac.com/tonc/text/toc.htm), a tutorial series written
for C, but it's what I based the ordering of this book's sections on.

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Ch 0: Development Setup - Rust GBA Tutorials</title>
<title>Ch 0: Development Setup - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">
@ -275,7 +275,10 @@ ROM is patched in place, so we don't even need to specify a new destination.</li
</li>
</ul>
<p>And you're finally done!</p>
<p>Of course, you probably want to make a script for all that, but it's up to you.</p>
<p>Of course, you probably want to make a script for all that, but it's up to you.
On our own project we have it mostly set up within a <code>Makefile.toml</code> which runs
using the <a href="https://github.com/sagiegurari/cargo-make">cargo-make</a> plugin. It's
not really the best plugin, but it's what's available.</p>
</main>

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>hello1 - Rust GBA Tutorials</title>
<title>hello1 - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">
@ -137,12 +137,12 @@
<div id="content" class="content">
<main>
<a class="header" href="#hello1" id="hello1"><h1>hello1</h1></a>
<p>Ready? Here goes:</p>
<p>Our first example will be a totally minimal, full magic number crazy town.
Ready? Here goes:</p>
<p><code>hello1.rs</code></p>
<pre><pre class="playpen"><code class="language-rust">#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}
@ -159,12 +159,12 @@ fn main(_argc: isize, _argv: *const *const u8) -&gt; isize {
}
}
</code></pre></pre>
<p>Throw that into your project, build the program (as described back in Chapter
0), and give it a run. You should see a red, green, and blue dot close-ish to
the middle of the screen. If you don't, something already went wrong. Double
check things, phone a friend, write your senators, try asking Ketsuban on the
<a href="https://discordapp.com/invite/aVESxV8">Rust Community Discord</a>, until you're
able to get your three dots going.</p>
<p>Throw that into your project skeleton, build the program (as described back in
Chapter 0), and give it a run in your emulator. You should see a red, green, and
blue dot close-ish to the middle of the screen. If you don't, something already
went wrong. Double check things, phone a friend, write your senators, try asking
Ketsuban on the <a href="https://discordapp.com/invite/aVESxV8">Rust Community Discord</a>,
until you're able to get your three dots going.</p>
<a class="header" href="#explaining-hello1" id="explaining-hello1"><h2>Explaining hello1</h2></a>
<p>So, what just happened? Even if you're used to Rust that might look pretty
strange. We'll go over each part extra carefully.</p>
@ -191,7 +191,6 @@ only life.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}
@ -203,9 +202,6 @@ Basically, if we somehow trigger a panic, this is where the program goes.
However, right now we don't know how to get any sort of message out to the user
so... we do nothing at all. We <em>can't even return</em> from here, so we just sit in
an infinite loop. The player will have to reset the universe from the outside.</p>
<p>The <code>#[cfg(not(test))]</code> part makes this item only exist in the program when
we're <em>not</em> in a test build. This is so that <code>cargo test</code> and such work right as
much as possible.</p>
<pre><pre class="playpen"><code class="language-rust">#[start]
fn main(_argc: isize, _argv: *const *const u8) -&gt; isize {
</code></pre></pre>
@ -271,40 +267,8 @@ magic numbers mean or do.</p>
<p>So we write some magic to the display control register once, then we write some
other magic to three locations of magic to the Video RAM. We get three dots,
each in their own location... so that second part makes sense at least.</p>
<p>We'll get into the magic number details in the other sections of this chapter.</p>
<a class="header" href="#sidebar-volatile" id="sidebar-volatile"><h2>Sidebar: Volatile</h2></a>
<p>We'll get into what all that is in a moment, but first let's ask ourselves: Why
are we doing <em>volatile</em> writes? You've probably never used it before at all.
What is volatile anyway?</p>
<p>Well, the optimizer is pretty aggressive some of the time, and so it'll skip
reads and writes when it thinks can. Like if you write to a pointer once, and
then again a moment later, and it didn't see any other reads in between, it'll
think that it can just skip doing that first write since it'll get overwritten
anyway. Sometimes that's right, but sometimes it's wrong.</p>
<p>Marking a read or write as <em>volatile</em> tells the compiler that it really must do
that action, and in the exact order that we wrote it out. It says that there
might even be special hardware side effects going on that the compiler isn't
aware of. In this case, the write to the display control register sets a video
mode, and the writes to the Video RAM set pixels that will show up on the
screen.</p>
<p>Similar to &quot;atomic&quot; operations you might have heard about, all volatile
operations are enforced to happen in the exact order that you specify them, but
only relative to other volatile operations. So something like</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
c.volatile_write(5);
a += b;
d.volatile_write(7);
#}</code></pre></pre>
<p>might end up changing <code>a</code> either before or after the change to <code>c</code> (since the
value of <code>a</code> doesn't affect the write to <code>c</code>), but the write to <code>d</code> will
<em>always</em> happen after the write to <code>c</code> even though the compiler doesn't see any
direct data dependency there.</p>
<p>If you ever use volatile stuff on other platforms it's important to note that
volatile doesn't make things thread-safe, you still need atomic for that.
However, the GBA doesn't have threads, so we don't have to worry about thread
safety concerns.</p>
<p>But what <em>exactly</em> is going on? Well that's what the whole rest of this chapter
(and this book) is about.</p>
</main>
@ -317,7 +281,7 @@ safety concerns.</p>
<a rel="next" href="../ch01/io_registers.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next" href="../ch01/volatile.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@ -335,7 +299,7 @@ safety concerns.</p>
<a href="../ch01/io_registers.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a href="../ch01/volatile.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>hello2 - Rust GBA Tutorials</title>
<title>hello2 - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html" class="active"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">
@ -142,7 +142,6 @@
<pre><pre class="playpen"><code class="language-rust">#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}
@ -202,7 +201,6 @@ pub unsafe fn mode3_pixel(col: isize, row: isize, color: u16) {
<pre><pre class="playpen"><code class="language-rust">#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Ch 1: Hello GBA - Rust GBA Tutorials</title>
<title>Ch 1: Hello GBA - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>IO Registers - Rust GBA Tutorials</title>
<title>IO Registers - 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">
@ -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/io_registers.html" class="active"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">
@ -176,7 +176,7 @@ array index is.</p>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../ch01/hello1.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../ch01/volatile.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@ -194,7 +194,7 @@ array index is.</p>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a href="../ch01/hello1.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a href="../ch01/volatile.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

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The Display Control Register - Rust GBA Tutorials</title>
<title>The Display Control Register - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html" class="active"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Video Memory Intro - Rust GBA Tutorials</title>
<title>Video Memory Intro - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html" class="active"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">

233
docs/ch01/volatile.html Normal file
View file

@ -0,0 +1,233 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Volatile - 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" 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></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="#volatile" id="volatile"><h1>Volatile</h1></a>
<p>Before we focus on what the numbers mean, first let's ask ourselves: Why are we
doing <em>volatile</em> writes? You've probably never used that keywords before at all.
What <em>is</em> volatile anyway?</p>
<p>Well, the optimizer is pretty aggressive, and so it'll skip reads and writes
when it thinks can. Like if you write to a pointer once, and then again a moment
later, and it didn't see any other reads in between, it'll think that it can
just skip doing that first write since it'll get overwritten anyway. Sometimes
that's correct, but sometimes it's not.</p>
<p>Marking a read or write as <em>volatile</em> tells the compiler that it really must do
that action, and in the exact order that we wrote it out. It says that there
might even be special hardware side effects going on that the compiler isn't
aware of. In this case, the write to the display control register sets a video
mode, and the writes to the Video RAM set pixels that will show up on the
screen.</p>
<p>Similar to &quot;atomic&quot; operations you might have heard about, all volatile
operations are enforced to happen in the exact order that you specify them, but
only relative to other volatile operations. So something like</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
c.volatile_write(5);
a += b;
d.volatile_write(7);
#}</code></pre></pre>
<p>might end up changing <code>a</code> either before or after the change to <code>c</code> (since the
value of <code>a</code> doesn't affect the write to <code>c</code>), but the write to <code>d</code> will
<em>always</em> happen after the write to <code>c</code>, even though the compiler doesn't see any
direct data dependency there.</p>
<p>If you ever go on to use volatile stuff on other platforms it's important to
note that volatile doesn't make things thread-safe, you still need atomic for
that. However, the GBA doesn't have threads, so we don't have to worry about
those sorts of thread safety concerns (there's interrupts, but that's another
matter).</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../ch01/hello1.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="../ch01/io_registers.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="../ch01/hello1.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="../ch01/io_registers.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

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Ch 2: User Input - Rust GBA Tutorials</title>
<title>Ch 2: User Input - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>light_cycle - Rust GBA Tutorials</title>
<title>light_cycle - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The Key Input Register - Rust GBA Tutorials</title>
<title>The Key Input Register - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The VCount Register - Rust GBA Tutorials</title>
<title>The VCount Register - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Ch 3: Memory and Objects - Rust GBA Tutorials</title>
<title>Ch 3: Memory and Objects - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Introduction - Rust GBA Tutorials</title>
<title>Introduction - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">
@ -137,8 +137,31 @@
<div id="content" class="content">
<main>
<a class="header" href="#introduction" id="introduction"><h1>Introduction</h1></a>
<p>Here's a book that'll help you program in Rust on the GBA.</p>
<p>It's very &quot;work in progress&quot;. At the moment there's only one demo program.</p>
<p>Here's a book that'll help you program in Rust on the Game Boy Advance (GBA).</p>
<p>It's a work in progress of course, but so is most of everything in Rust.</p>
<a class="header" href="#style-and-purpose" id="style-and-purpose"><h2>Style and Purpose</h2></a>
<p>I'm out to teach you how to program in Rust on the GBA, obviously. However,
while there <em>is</em> a <a href="https://github.com/rust-console/gba">gba</a> crate, and while I
genuinely believe it to be a good and useful crate for GBA programming, we <em>will
not</em> be using the <code>gba</code> crate within this book. In fact we won't be using any
crates at all. We can call it the <a href="https://handmadehero.org/">Handmade Hero</a>
approach, if you like.</p>
<p>I don't want to just teach you how to use the <code>gba</code> crate, I want to teach you
what you'd need to know to write the crate from scratch if it wasn't there.</p>
<p>Each chapter of the book will focus on a few things you'll need to know about
GBA programming and then present a fully self-contained example that puts those
ideas into action. Just one file per example, no dependencies, no external
assets, no fuss. The examples will be in the text of the book within code
blocks, but also you can find them in the <a href="https://github.com/rust-console/gba/tree/master/examples">examples
directory</a> of the repo
if you want to get them that way.</p>
<a class="header" href="#expected-knowledge" id="expected-knowledge"><h2>Expected Knowledge</h2></a>
<p>I will try not to ask too much of the reader ahead of time, but you are expected
to have already read <a href="https://doc.rust-lang.org/book/">The Rust Book</a>.</p>
<p>It's very difficult to know when you've said something that someone else won't
already know about. Or if you're presenting ideas out of order. If things aren't
clear please <a href="https://github.com/rust-console/gba/issues">file an issue</a> and
we'll try to address it.</p>
<a class="header" href="#getting-help" id="getting-help"><h2>Getting Help</h2></a>
<p>If you want to contact us you should join the <a href="https://discordapp.com/invite/aVESxV8">Rust Community
Discord</a> and ask in the <code>#gamedev</code>
@ -148,9 +171,10 @@ channel.</p>
<li><code>Lokathor</code> is the fool who decided to write a crate and book for it.</li>
</ul>
<p>If it's <em>not</em> a GBA specific question then you can probably ask any of the other
folks in the server as well.</p>
<a class="header" href="#other-works" id="other-works"><h2>Other Works</h2></a>
<p>If you want to read more about developing on the GBA there are some other good resources as well:</p>
folks in the server as well (there's a few hundred folks).</p>
<a class="header" href="#further-reading" id="further-reading"><h2>Further Reading</h2></a>
<p>If you want to read more about developing on the GBA there are some other good
resources as well:</p>
<ul>
<li><a href="https://www.coranac.com/tonc/text/toc.htm">Tonc</a>, a tutorial series written
for C, but it's what I based the ordering of this book's sections on.</li>

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Introduction - Rust GBA Tutorials</title>
<title>Introduction - 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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">
@ -137,8 +137,31 @@
<div id="content" class="content">
<main>
<a class="header" href="#introduction" id="introduction"><h1>Introduction</h1></a>
<p>Here's a book that'll help you program in Rust on the GBA.</p>
<p>It's very &quot;work in progress&quot;. At the moment there's only one demo program.</p>
<p>Here's a book that'll help you program in Rust on the Game Boy Advance (GBA).</p>
<p>It's a work in progress of course, but so is most of everything in Rust.</p>
<a class="header" href="#style-and-purpose" id="style-and-purpose"><h2>Style and Purpose</h2></a>
<p>I'm out to teach you how to program in Rust on the GBA, obviously. However,
while there <em>is</em> a <a href="https://github.com/rust-console/gba">gba</a> crate, and while I
genuinely believe it to be a good and useful crate for GBA programming, we <em>will
not</em> be using the <code>gba</code> crate within this book. In fact we won't be using any
crates at all. We can call it the <a href="https://handmadehero.org/">Handmade Hero</a>
approach, if you like.</p>
<p>I don't want to just teach you how to use the <code>gba</code> crate, I want to teach you
what you'd need to know to write the crate from scratch if it wasn't there.</p>
<p>Each chapter of the book will focus on a few things you'll need to know about
GBA programming and then present a fully self-contained example that puts those
ideas into action. Just one file per example, no dependencies, no external
assets, no fuss. The examples will be in the text of the book within code
blocks, but also you can find them in the <a href="https://github.com/rust-console/gba/tree/master/examples">examples
directory</a> of the repo
if you want to get them that way.</p>
<a class="header" href="#expected-knowledge" id="expected-knowledge"><h2>Expected Knowledge</h2></a>
<p>I will try not to ask too much of the reader ahead of time, but you are expected
to have already read <a href="https://doc.rust-lang.org/book/">The Rust Book</a>.</p>
<p>It's very difficult to know when you've said something that someone else won't
already know about. Or if you're presenting ideas out of order. If things aren't
clear please <a href="https://github.com/rust-console/gba/issues">file an issue</a> and
we'll try to address it.</p>
<a class="header" href="#getting-help" id="getting-help"><h2>Getting Help</h2></a>
<p>If you want to contact us you should join the <a href="https://discordapp.com/invite/aVESxV8">Rust Community
Discord</a> and ask in the <code>#gamedev</code>
@ -148,9 +171,10 @@ channel.</p>
<li><code>Lokathor</code> is the fool who decided to write a crate and book for it.</li>
</ul>
<p>If it's <em>not</em> a GBA specific question then you can probably ask any of the other
folks in the server as well.</p>
<a class="header" href="#other-works" id="other-works"><h2>Other Works</h2></a>
<p>If you want to read more about developing on the GBA there are some other good resources as well:</p>
folks in the server as well (there's a few hundred folks).</p>
<a class="header" href="#further-reading" id="further-reading"><h2>Further Reading</h2></a>
<p>If you want to read more about developing on the GBA there are some other good
resources as well:</p>
<ul>
<li><a href="https://www.coranac.com/tonc/text/toc.htm">Tonc</a>, a tutorial series written
for C, but it's what I based the ordering of this book's sections on.</li>

View file

@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Rust GBA Tutorials</title>
<title>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">
@ -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/io_registers.html"><strong aria-hidden="true">3.2.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.3.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.4.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.5.</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></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></ol>
</nav>
<div id="page-wrapper" class="page-wrapper">
@ -102,7 +102,7 @@
</div>
<h1 class="menu-title">Rust GBA Tutorials</h1>
<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">
@ -137,8 +137,31 @@
<div id="content" class="content">
<main>
<a class="header" href="#introduction" id="introduction"><h1>Introduction</h1></a>
<p>Here's a book that'll help you program in Rust on the GBA.</p>
<p>It's very &quot;work in progress&quot;. At the moment there's only one demo program.</p>
<p>Here's a book that'll help you program in Rust on the Game Boy Advance (GBA).</p>
<p>It's a work in progress of course, but so is most of everything in Rust.</p>
<a class="header" href="#style-and-purpose" id="style-and-purpose"><h2>Style and Purpose</h2></a>
<p>I'm out to teach you how to program in Rust on the GBA, obviously. However,
while there <em>is</em> a <a href="https://github.com/rust-console/gba">gba</a> crate, and while I
genuinely believe it to be a good and useful crate for GBA programming, we <em>will
not</em> be using the <code>gba</code> crate within this book. In fact we won't be using any
crates at all. We can call it the <a href="https://handmadehero.org/">Handmade Hero</a>
approach, if you like.</p>
<p>I don't want to just teach you how to use the <code>gba</code> crate, I want to teach you
what you'd need to know to write the crate from scratch if it wasn't there.</p>
<p>Each chapter of the book will focus on a few things you'll need to know about
GBA programming and then present a fully self-contained example that puts those
ideas into action. Just one file per example, no dependencies, no external
assets, no fuss. The examples will be in the text of the book within code
blocks, but also you can find them in the <a href="https://github.com/rust-console/gba/tree/master/examples">examples
directory</a> of the repo
if you want to get them that way.</p>
<a class="header" href="#expected-knowledge" id="expected-knowledge"><h2>Expected Knowledge</h2></a>
<p>I will try not to ask too much of the reader ahead of time, but you are expected
to have already read <a href="https://doc.rust-lang.org/book/">The Rust Book</a>.</p>
<p>It's very difficult to know when you've said something that someone else won't
already know about. Or if you're presenting ideas out of order. If things aren't
clear please <a href="https://github.com/rust-console/gba/issues">file an issue</a> and
we'll try to address it.</p>
<a class="header" href="#getting-help" id="getting-help"><h2>Getting Help</h2></a>
<p>If you want to contact us you should join the <a href="https://discordapp.com/invite/aVESxV8">Rust Community
Discord</a> and ask in the <code>#gamedev</code>
@ -148,9 +171,10 @@ channel.</p>
<li><code>Lokathor</code> is the fool who decided to write a crate and book for it.</li>
</ul>
<p>If it's <em>not</em> a GBA specific question then you can probably ask any of the other
folks in the server as well.</p>
<a class="header" href="#other-works" id="other-works"><h2>Other Works</h2></a>
<p>If you want to read more about developing on the GBA there are some other good resources as well:</p>
folks in the server as well (there's a few hundred folks).</p>
<a class="header" href="#further-reading" id="further-reading"><h2>Further Reading</h2></a>
<p>If you want to read more about developing on the GBA there are some other good
resources as well:</p>
<ul>
<li><a href="https://www.coranac.com/tonc/text/toc.htm">Tonc</a>, a tutorial series written
for C, but it's what I based the ordering of this book's sections on.</li>
@ -300,7 +324,10 @@ ROM is patched in place, so we don't even need to specify a new destination.</li
</li>
</ul>
<p>And you're finally done!</p>
<p>Of course, you probably want to make a script for all that, but it's up to you.</p>
<p>Of course, you probably want to make a script for all that, but it's up to you.
On our own project we have it mostly set up within a <code>Makefile.toml</code> which runs
using the <a href="https://github.com/sagiegurari/cargo-make">cargo-make</a> plugin. It's
not really the best plugin, but it's what's available.</p>
<a class="header" href="#ch-1-hello-gba" id="ch-1-hello-gba"><h1>Ch 1: Hello GBA</h1></a>
<p>Traditionally a person writes a &quot;hello, world&quot; program so that they can test
that their development environment is setup properly and to just get a feel for
@ -310,12 +337,12 @@ will look like. All that stuff.</p>
GBA has no terminal, but it does have a screen, so instead we're going to draw
three dots to the screen.</p>
<a class="header" href="#hello1" id="hello1"><h1>hello1</h1></a>
<p>Ready? Here goes:</p>
<p>Our first example will be a totally minimal, full magic number crazy town.
Ready? Here goes:</p>
<p><code>hello1.rs</code></p>
<pre><pre class="playpen"><code class="language-rust">#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}
@ -332,12 +359,12 @@ fn main(_argc: isize, _argv: *const *const u8) -&gt; isize {
}
}
</code></pre></pre>
<p>Throw that into your project, build the program (as described back in Chapter
0), and give it a run. You should see a red, green, and blue dot close-ish to
the middle of the screen. If you don't, something already went wrong. Double
check things, phone a friend, write your senators, try asking Ketsuban on the
<a href="https://discordapp.com/invite/aVESxV8">Rust Community Discord</a>, until you're
able to get your three dots going.</p>
<p>Throw that into your project skeleton, build the program (as described back in
Chapter 0), and give it a run in your emulator. You should see a red, green, and
blue dot close-ish to the middle of the screen. If you don't, something already
went wrong. Double check things, phone a friend, write your senators, try asking
Ketsuban on the <a href="https://discordapp.com/invite/aVESxV8">Rust Community Discord</a>,
until you're able to get your three dots going.</p>
<a class="header" href="#explaining-hello1" id="explaining-hello1"><h2>Explaining hello1</h2></a>
<p>So, what just happened? Even if you're used to Rust that might look pretty
strange. We'll go over each part extra carefully.</p>
@ -364,7 +391,6 @@ only life.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}
@ -376,9 +402,6 @@ Basically, if we somehow trigger a panic, this is where the program goes.
However, right now we don't know how to get any sort of message out to the user
so... we do nothing at all. We <em>can't even return</em> from here, so we just sit in
an infinite loop. The player will have to reset the universe from the outside.</p>
<p>The <code>#[cfg(not(test))]</code> part makes this item only exist in the program when
we're <em>not</em> in a test build. This is so that <code>cargo test</code> and such work right as
much as possible.</p>
<pre><pre class="playpen"><code class="language-rust">#[start]
fn main(_argc: isize, _argv: *const *const u8) -&gt; isize {
</code></pre></pre>
@ -444,16 +467,17 @@ magic numbers mean or do.</p>
<p>So we write some magic to the display control register once, then we write some
other magic to three locations of magic to the Video RAM. We get three dots,
each in their own location... so that second part makes sense at least.</p>
<p>We'll get into the magic number details in the other sections of this chapter.</p>
<a class="header" href="#sidebar-volatile" id="sidebar-volatile"><h2>Sidebar: Volatile</h2></a>
<p>We'll get into what all that is in a moment, but first let's ask ourselves: Why
are we doing <em>volatile</em> writes? You've probably never used it before at all.
What is volatile anyway?</p>
<p>Well, the optimizer is pretty aggressive some of the time, and so it'll skip
reads and writes when it thinks can. Like if you write to a pointer once, and
then again a moment later, and it didn't see any other reads in between, it'll
think that it can just skip doing that first write since it'll get overwritten
anyway. Sometimes that's right, but sometimes it's wrong.</p>
<p>But what <em>exactly</em> is going on? Well that's what the whole rest of this chapter
(and this book) is about.</p>
<a class="header" href="#volatile" id="volatile"><h1>Volatile</h1></a>
<p>Before we focus on what the numbers mean, first let's ask ourselves: Why are we
doing <em>volatile</em> writes? You've probably never used that keywords before at all.
What <em>is</em> volatile anyway?</p>
<p>Well, the optimizer is pretty aggressive, and so it'll skip reads and writes
when it thinks can. Like if you write to a pointer once, and then again a moment
later, and it didn't see any other reads in between, it'll think that it can
just skip doing that first write since it'll get overwritten anyway. Sometimes
that's correct, but sometimes it's not.</p>
<p>Marking a read or write as <em>volatile</em> tells the compiler that it really must do
that action, and in the exact order that we wrote it out. It says that there
might even be special hardware side effects going on that the compiler isn't
@ -472,12 +496,13 @@ d.volatile_write(7);
#}</code></pre></pre>
<p>might end up changing <code>a</code> either before or after the change to <code>c</code> (since the
value of <code>a</code> doesn't affect the write to <code>c</code>), but the write to <code>d</code> will
<em>always</em> happen after the write to <code>c</code> even though the compiler doesn't see any
<em>always</em> happen after the write to <code>c</code>, even though the compiler doesn't see any
direct data dependency there.</p>
<p>If you ever use volatile stuff on other platforms it's important to note that
volatile doesn't make things thread-safe, you still need atomic for that.
However, the GBA doesn't have threads, so we don't have to worry about thread
safety concerns.</p>
<p>If you ever go on to use volatile stuff on other platforms it's important to
note that volatile doesn't make things thread-safe, you still need atomic for
that. However, the GBA doesn't have threads, so we don't have to worry about
those sorts of thread safety concerns (there's interrupts, but that's another
matter).</p>
<a class="header" href="#io-registers" id="io-registers"><h1>IO Registers</h1></a>
<p>The GBA has a large number of <strong>IO Registers</strong> (not to be confused with CPU
registers). These are special memory locations from <code>0x04000000</code> to
@ -702,7 +727,6 @@ binary to make sense of it.</p>
<pre><pre class="playpen"><code class="language-rust">#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}
@ -762,7 +786,6 @@ pub unsafe fn mode3_pixel(col: isize, row: isize, color: u16) {
<pre><pre class="playpen"><code class="language-rust">#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &amp;core::panic::PanicInfo) -&gt; ! {
loop {}

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,7 +1,6 @@
#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}

View file

@ -1,7 +1,6 @@
#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
@ -10,7 +9,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
unsafe {
DISPCNT.write_volatile(MODE3 | BG2);
DISPCNT.write(MODE3 | BG2);
mode3_pixel(120, 80, rgb16(31, 0, 0));
mode3_pixel(136, 80, rgb16(0, 31, 0));
mode3_pixel(120, 96, rgb16(0, 0, 31));
@ -18,7 +17,22 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
}
}
pub const DISPCNT: *mut u16 = 0x04000000 as *mut u16;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[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 unsafe fn offset(self, count: isize) -> Self {
VolatilePtr(self.0.wrapping_offset(count))
}
}
pub const DISPCNT: VolatilePtr<u16> = VolatilePtr(0x04000000 as *mut u16);
pub const MODE3: u16 = 3;
pub const BG2: u16 = 0b100_0000_0000;
@ -30,5 +44,5 @@ pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
}
pub unsafe fn mode3_pixel(col: isize, row: isize, color: u16) {
(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write_volatile(color);
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write(color);
}

View file

@ -1,41 +0,0 @@
#![feature(start)]
#![no_std]
extern crate gba;
use gba::{io_registers::*, video_ram::*};
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let mode3bg2 = {
let mut setting = DisplayControlSetting::default();
setting.set_display_bg2(true);
setting.set_mode(DisplayControlMode::Bitmap3);
setting
};
set_display_control(mode3bg2);
let red = rgb16(31, 0, 0);
let green = rgb16(0, 31, 0);
loop {
let this_frame_keys = key_input();
let this_frame_key_raw: u16 = unsafe { core::mem::transmute(this_frame_keys) };
wait_until_vblank();
for i in 0..16 {
let key = ((this_frame_key_raw >> i) & 1) > 0;
mode3_draw_pixel(15 - i, 0, if key { green } else { red });
mode3_draw_pixel(15 - i, 1, if key { green } else { red });
}
wait_until_vdraw();
}
}

View file

@ -1,7 +1,6 @@
#![feature(start)]
#![no_std]
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
@ -10,7 +9,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
unsafe {
DISPCNT.write_volatile(MODE3 | BG2);
DISPCNT.write(MODE3 | BG2);
}
let mut px = SCREEN_WIDTH / 2;
@ -19,7 +18,7 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
loop {
// read the input for this frame
let this_frame_keys = read_key_input();
let this_frame_keys = key_input();
// adjust game state and wait for vblank
px += 2 * this_frame_keys.column_direction() as isize;
@ -53,7 +52,22 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
}
}
pub const DISPCNT: *mut u16 = 0x04000000 as *mut u16;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[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 unsafe fn offset(self, count: isize) -> Self {
VolatilePtr(self.0.wrapping_offset(count))
}
}
pub const DISPCNT: VolatilePtr<u16> = VolatilePtr(0x04000000 as *mut u16);
pub const MODE3: u16 = 3;
pub const BG2: u16 = 0b100_0000_0000;
@ -68,24 +82,24 @@ pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
pub unsafe fn mode3_clear_screen(color: u16) {
let color = color as u32;
let bulk_color = color << 16 | color;
let mut ptr = VRAM as *mut u32;
let mut ptr = VolatilePtr(VRAM as *mut u32);
for _ in 0..SCREEN_HEIGHT {
for _ in 0..(SCREEN_WIDTH / 2) {
ptr.write_volatile(bulk_color);
ptr.write(bulk_color);
ptr = ptr.offset(1);
}
}
}
pub unsafe fn mode3_draw_pixel(col: isize, row: isize, color: u16) {
(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write_volatile(color);
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write(color);
}
pub unsafe fn mode3_read_pixel(col: isize, row: isize) -> u16 {
(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).read_volatile()
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).read()
}
pub const KEYINPUT: *mut u16 = 0x400_0130 as *mut u16;
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)]
@ -101,8 +115,8 @@ pub enum TriBool {
Plus = 1,
}
pub fn read_key_input() -> KeyInputSetting {
unsafe { KeyInputSetting(KEYINPUT.read_volatile() ^ 0b0000_0011_1111_1111) }
pub fn key_input() -> KeyInputSetting {
unsafe { KeyInputSetting(KEYINPUT.read() ^ 0b0000_0011_1111_1111) }
}
pub const KEY_A: u16 = 1 << 0;
@ -146,16 +160,16 @@ impl KeyInputSetting {
}
}
pub const VCOUNT: *mut u16 = 0x0400_0006 as *mut u16;
pub const VCOUNT: VolatilePtr<u16> = VolatilePtr(0x0400_0006 as *mut u16);
pub fn read_vcount() -> u16 {
unsafe { VCOUNT.read_volatile() }
pub fn vcount() -> u16 {
unsafe { VCOUNT.read() }
}
pub fn wait_until_vblank() {
while read_vcount() < SCREEN_HEIGHT as u16 {}
while vcount() < SCREEN_HEIGHT as u16 {}
}
pub fn wait_until_vdraw() {
while read_vcount() >= SCREEN_HEIGHT as u16 {}
while vcount() >= SCREEN_HEIGHT as u16 {}
}

View file

@ -1,5 +1,5 @@
#![cfg_attr(not(test), no_std)]
#![feature(asm)]
#![cfg_attr(not(test), feature(asm))]
#![warn(missing_docs)]
//! This crate helps you write GBA ROMs.
@ -70,15 +70,22 @@ pub fn modulus(numerator: i32, denominator: i32) -> i32 {
#[inline]
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"
#[cfg(not(test))]
{
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)
}
#[cfg(test)]
{
(numerator / denominator, numerator % denominator)
}
(div_out, mod_out)
}