mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-23 19:01:30 +11:00
edits, cleanups, and a goal for ch3
This commit is contained in:
parent
3a355db578
commit
241fb1746c
|
@ -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
|
||||
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
[book]
|
||||
title = "Rust GBA Tutorials"
|
||||
title = "Rust GBA Guide"
|
||||
authors = ["Lokathor"]
|
||||
#description = "Rust GBA Tutorials."
|
||||
|
||||
[build]
|
||||
build-dir = "../docs"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
70
book/src/ch01/volatile.md
Normal 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))
|
||||
}
|
||||
}
|
||||
```
|
|
@ -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;
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
```
|
||||
|
|
|
@ -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 {}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
|
@ -159,12 +159,12 @@ fn main(_argc: isize, _argv: *const *const u8) -> 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: &core::panic::PanicInfo) -> ! {
|
||||
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) -> 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 "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</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>
|
||||
|
||||
|
|
|
@ -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: &core::panic::PanicInfo) -> ! {
|
||||
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: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
233
docs/ch01/volatile.html
Normal 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 "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</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>
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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 "work in progress". 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>
|
||||
|
|
|
@ -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 "work in progress". 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>
|
||||
|
|
|
@ -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 "work in progress". 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 "hello, world" 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: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
|
@ -332,12 +359,12 @@ fn main(_argc: isize, _argv: *const *const u8) -> 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: &core::panic::PanicInfo) -> ! {
|
||||
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) -> 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: &core::panic::PanicInfo) -> ! {
|
||||
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: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,6 @@
|
|||
#![feature(start)]
|
||||
#![no_std]
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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 {}
|
||||
}
|
||||
|
|
19
src/lib.rs
19
src/lib.rs
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue