<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Jonah Nestrick</title>
    <subtitle>My personal blog</subtitle>
    <link rel="self" type="application/atom+xml" href="https://jonahnestrick.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://jonahnestrick.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-05-15T16:47:33+00:00</updated>
    <id>https://jonahnestrick.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Rust x GBA: Setup and Pixels</title>
        <published>2026-05-15T16:47:33+00:00</published>
        <updated>2026-05-15T16:47:33+00:00</updated>
        
        <author>
          <name>
            
              Jonah Nestrick &lt;jonah.nestrick@gmail.com&gt;
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://jonahnestrick.com/blog/rust-gba-tutorial-1/"/>
        <id>https://jonahnestrick.com/blog/rust-gba-tutorial-1/</id>
        
        <content type="html" xml:base="https://jonahnestrick.com/blog/rust-gba-tutorial-1/">&lt;p&gt;This guide will show you how to setup a Rust project that builds a basic rom which runs on the Game Boy Advance. It assumes you already know the basics of Rust and are familiar with software development. If you aren&#x27;t familiar with Rust, checkout the [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;&quot;&gt;Rust Book&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;&quot;&gt;doc.rust-lang.org&#x2F;book&#x2F;&lt;&#x2F;a&gt;)
as it a great resource for learning the very rewarding programming language.&lt;&#x2F;p&gt;
&lt;div class=&quot;callout callout--info&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&#x2F;&gt;&lt;path d=&quot;M12 16v-4&quot;&#x2F;&gt;&lt;path d=&quot;M12 8h.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;If you want to skip ahead, the completed lesson code and all code for this tutorial can be found here:&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;undecidedapollo&#x2F;gba-tutorial&#x2F;tree&#x2F;lesson-01&quot;&gt;Lesson 01&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;undecidedapollo&#x2F;gba-tutorial&#x2F;tree&#x2F;lesson-01&quot;&gt;github.com&#x2F;undecidedapollo&#x2F;gba-tutorial&#x2F;tree&#x2F;lesson-01&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;


&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;background&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#background&quot;&gt;Background&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This is the part where I tell you my life story before giving you the recipe to make &quot;Chocolate Chip Cookies&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#setup&quot;&gt;Click here to skip ahead to the project setup&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Last year around this time I wanted to work on a low-level project with Rust. Most of my day job I spent building APIs in TypeScript but Rust had interested me in its ability to model program execution in a safe, performant way allowing developers to write code that performs at native speeds while still having the conveniences of a modern language.&lt;&#x2F;p&gt;
&lt;p&gt;I started out buying a couple [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;store-usa.arduino.cc&#x2F;products&#x2F;nano-esp32&quot;&gt;Arduino ESP32&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;store-usa.arduino.cc&#x2F;products&#x2F;nano-esp32&quot;&gt;store-usa.arduino.cc&#x2F;products&#x2F;nano-esp32&lt;&#x2F;a&gt;)
boards and did the basics, blinking lights, ESPNow Ping and Pong, etc. While fun, you also need to be good with electronics to do any useful &quot;work&quot; with an ESP32 and that isn&#x27;t my strong suit.&lt;&#x2F;p&gt;
&lt;p&gt;After spending some time searching, I landed on the Game Boy Advance as a fun platform to try and develop for. It has a 32-bit Arm processor, input buttons on the device, has output like a screen and speakers, MMIO (Memory Mapped Input &#x2F; Output), and is standardized in the sense that what runs on one Game Boy Advance will run on any other. With all of these features it also had some tight restrictions such as limited memory, limited rom space, VRAM limitations, sprite limitations, etc.&lt;&#x2F;p&gt;
&lt;p&gt;On my mind at the time was the quote by Orson Welles:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The enemy of art is the absence of limitations&quot;
- Orson Welles&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I started out on this journey figuring out what existed in the space already. I found two crates with different goals in mind:&lt;&#x2F;p&gt;
&lt;p&gt;The first I saw was the crate [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;&quot;&gt;gba&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;&quot;&gt;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;&lt;&#x2F;a&gt;)
which posits itself as a crate that does just enough to make a Rust safe API to work with the hardware from the language.&lt;&#x2F;p&gt;
&lt;p&gt;The docs said it best:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This crate provides an API to interact with the GBA that is safe, but with
minimal restrictions on what components can be changed when. If you’d like
an API where the borrow checker provides stronger control over component
access then the [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;agb&#x2F;latest&#x2F;agb&#x2F;&quot;&gt;agb&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;agb&#x2F;latest&#x2F;agb&#x2F;&quot;&gt;docs.rs&#x2F;agb&#x2F;latest&#x2F;agb&#x2F;&lt;&#x2F;a&gt;)
crate might be what you want.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That statement sold me as I wanted low-level Rust with as little hand holding as possible so I dove in to the &lt;code&gt;gba&lt;&#x2F;code&gt; crate.&lt;&#x2F;p&gt;
&lt;p&gt;From there I read the repo, setup a project, and followed some great tutorials from other talented developers on how to get started with GBA development.&lt;&#x2F;p&gt;
&lt;p&gt;The first tutorial I followed was [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shanesnover.com&#x2F;2024&#x2F;02&#x2F;07&#x2F;intro-to-rust-on-gba.html&quot;&gt;Shane&#x27;s dev blog - &quot;Building GBA Games in Rust&quot;&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shanesnover.com&#x2F;2024&#x2F;02&#x2F;07&#x2F;intro-to-rust-on-gba.html&quot;&gt;shanesnover.com&#x2F;2024&#x2F;02&#x2F;07&#x2F;intro-to-rust-on-gba.html&lt;&#x2F;a&gt;)
which covered Shane&#x27;s learning process on getting started with GBA development on Rust. Best of all was a link to his [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ssnover&#x2F;game-of-life&quot;&gt;&quot;Conway&#x27;s Game of Life&quot; repository&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ssnover&#x2F;game-of-life&quot;&gt;github.com&#x2F;ssnover&#x2F;game-of-life&lt;&#x2F;a&gt;)
containing a functional GBA Rust project which became the building block for my gba games (and we will pull some features and code from it as we go). The blog post is worth reading as it covers GBA development at a high level while also providing a concrete example with the &quot;Game of Life&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;After this, the main tutorials that I followed was [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kylehalladay.com&#x2F;gba.html&quot;&gt;Kyle Halladay - &quot;GBA Tutorial&quot;&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kylehalladay.com&#x2F;gba.html&quot;&gt;kylehalladay.com&#x2F;gba.html&lt;&#x2F;a&gt;)
set of blog posts which covered how to get started with GBA development in C++. From drawing on the screen to drawing a sprite, drawing background layers, user input, it was a great resource and I highly recommend you read it when you get a chance. We will cover similar topics in this tutorial in a similar order and you will find that it is a strong inspiration for the pacing and direction of this tutorial.&lt;&#x2F;p&gt;
&lt;p&gt;Another great resource which dove deep into the hardware and explained how the Game Boy Advance actually worked under the hood was [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coranac.com&#x2F;tonc&#x2F;text&#x2F;toc.htm&quot;&gt;Tonc&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coranac.com&#x2F;tonc&#x2F;text&#x2F;toc.htm&quot;&gt;coranac.com&#x2F;tonc&#x2F;text&#x2F;toc.htm&lt;&#x2F;a&gt;)
. This was a bit harder to read as it was very technical but it contained a trove of information such as info on the underlying hardware, memory layout, quirks, tips, pointers, code examples, etc. When it came time to understanding a new system like sprites or background modes, I enjoyed reading the info on each of the modes, what you can do with them, and code examples on how to best leverage them that Tonc provided. I would recommend bookmarking that site as it has a wealth of information that will come in handy later.&lt;&#x2F;p&gt;
&lt;p&gt;This tutorial will rehash many of the things Kyle covered in his tutorials but will be focused solely on Rust and specifically the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;&quot;&gt;gba&lt;&#x2F;a&gt; crate. Since we are working on an embedded system, we will only have access to &lt;code&gt;core&lt;&#x2F;code&gt; (you can use &lt;code&gt;alloc&lt;&#x2F;code&gt; also but we won&#x27;t for this project) and will not have access to the traditional, expansive Rust standard library.&lt;&#x2F;p&gt;
&lt;p&gt;This tutorial will cover the basics to get you up and running and future tutorials may be created that cover more advanced topics.&lt;&#x2F;p&gt;
&lt;p&gt;At the end of this tutorial you will have a Rust project that builds a functional GBA rom that you can use as a foundation for your own games.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setup&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#setup&quot;&gt;Setting Up Your Dev Environment&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;rust&quot;&gt;Rust&lt;&#x2F;h4&gt;
&lt;p&gt;There are a few prerequisites before we get started.&lt;&#x2F;p&gt;
&lt;p&gt;You will need to have Rust &#x2F; Cargo installed on your machine. We will be using a nightly version of the compiler. If you have a recent version of Rust &#x2F; Cargo installed it should download the nightly version you need when we configure the project later on (thanks &lt;code&gt;rust-toolchain.toml&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;If you don&#x27;t have Rust installed, you can use [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rustup.rs&#x2F;&quot;&gt;RustUp&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rustup.rs&#x2F;&quot;&gt;rustup.rs&#x2F;&lt;&#x2F;a&gt;)
to get your machine setup.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;other-software&quot;&gt;Other Software&lt;&#x2F;h4&gt;
&lt;p&gt;Next we will follow the instructions from the [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;#how-to-make-your-own-gba-project-using-this-crate&quot;&gt;gba&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;#how-to-make-your-own-gba-project-using-this-crate&quot;&gt;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;&lt;&#x2F;a&gt;)
crate on how to setup our own gba project. There are a few things we need to download and setup here but it is just a one time setup.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;arm-binutils&quot;&gt;ARM Binutils&lt;&#x2F;h5&gt;
&lt;p&gt;First we will need to download the [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;Tools%20and%20Software&#x2F;GNU%20Toolchain&quot;&gt;ARM Binutils&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;Tools%20and%20Software&#x2F;GNU%20Toolchain&quot;&gt;developer.arm.com&#x2F;Tools%20and%20Software&#x2F;GNU%20Toolchain&lt;&#x2F;a&gt;)
.&lt;&#x2F;p&gt;
&lt;div class=&quot;callout callout--info&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&#x2F;&gt;&lt;path d=&quot;M12 16v-4&quot;&#x2F;&gt;&lt;path d=&quot;M12 8h.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;You may be able to use a package manager for this.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Mac&lt;&#x2F;strong&gt; You can install these utilities using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;formulae.brew.sh&#x2F;formula&#x2F;arm-none-eabi-binutils&quot;&gt;Homebrew&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;formulae.brew.sh&#x2F;formula&#x2F;arm-none-eabi-binutils&quot;&gt;https:&#x2F;&#x2F;formulae.brew.sh&#x2F;formula&#x2F;arm-none-eabi-binutils&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; arm-none-eabi-binutils&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;

&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The website is a bit confusing as it contains many options to download, you will need to narrow down the installer you need by:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Operating System (Windows, Linux, Mac)&lt;&#x2F;li&gt;
&lt;li&gt;Architecture Intel (x86) vs. ARM (aarch), 32-bit vs. 64 bit, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Toolchain, we are looking for &quot;bare-metal target (&lt;code&gt;arm-none-eabi&lt;&#x2F;code&gt;)&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;div class=&quot;callout callout--tip&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&#x2F;&gt;&lt;line x1=&quot;12&quot; x2=&quot;12&quot; y1=&quot;8&quot; y2=&quot;12&quot;&#x2F;&gt;&lt;line x1=&quot;12&quot; x2=&quot;12&quot; y1=&quot;16&quot; y2=&quot;16.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;The files I found most helpful were:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&quot;Windows (mingw-w64-x86_64) hosted cross toolchains&quot; -&amp;gt; &quot;AArch32 bare-metal target (arm-none-eabi)&quot;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-mingw-w64-x86_64-arm-none-eabi.msi&quot;&gt;arm-gnu-toolchain-15.2.rel1-mingw-w64-x86_64-arm-none-eabi.msi&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-mingw-w64-x86_64-arm-none-eabi.msi&quot;&gt;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-mingw-w64-x86_64-arm-none-eabi.msi&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&quot;macOS (Apple silicon) hosted cross toolchains&quot; -&amp;gt; &quot;AArch32 bare-metal target (arm-none-eabi)&quot;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-darwin-arm64-arm-none-eabi.pkg&quot;&gt;arm-gnu-toolchain-15.2.rel1-darwin-arm64-arm-none-eabi.pkg&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-darwin-arm64-arm-none-eabi.pkg&quot;&gt;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-darwin-arm64-arm-none-eabi.pkg&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&quot;x86_64 Linux hosted cross toolchains&quot; -&amp;gt; &quot;AArch32 bare-metal target (arm-none-eabi)&quot;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi.tar.xz&quot;&gt;arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi.tar.xz&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi.tar.xz&quot;&gt;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi.tar.xz&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&quot;aarch64 Linux hosted cross toolchains&quot; -&amp;gt; &quot;AArch32 bare-metal target (arm-none-eabi)&quot;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-aarch64-arm-none-eabi.tar.xz&quot;&gt;arm-gnu-toolchain-15.2.rel1-aarch64-arm-none-eabi.tar.xz&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-aarch64-arm-none-eabi.tar.xz&quot;&gt;developer.arm.com&#x2F;-&#x2F;media&#x2F;Files&#x2F;downloads&#x2F;gnu&#x2F;15.2.rel1&#x2F;binrel&#x2F;arm-gnu-toolchain-15.2.rel1-aarch64-arm-none-eabi.tar.xz&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;


&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;After installation, you will need to alter your path so that the binary &lt;code&gt;arm-none-eabi-ld&lt;&#x2F;code&gt; from the ARM tools is in your path.&lt;&#x2F;p&gt;
&lt;p&gt;On Windows, this should be: &lt;code&gt;C:\Program Files\Arm\GNU Toolchain mingw-w64-x86_64-arm-none-eabi\bin&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.architectryan.com&#x2F;2018&#x2F;03&#x2F;17&#x2F;add-to-the-path-on-windows-10&#x2F;&quot;&gt;How to set PATH variable on Windows&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On Mac and Linux, you will need to update your shell environment file to point to the utilities. If you used a package manager you should be able to skip this step.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;gba-emulator&quot;&gt;GBA Emulator&lt;&#x2F;h5&gt;
&lt;p&gt;Lastly we will need an emulator to run our game. According to the &lt;code&gt;gba&lt;&#x2F;code&gt; crate, the roms created by the crate can be run on devices directly but require extra steps that won&#x27;t be covered in this tutorial.&lt;&#x2F;p&gt;
&lt;p&gt;We will be using the [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mgba.io&#x2F;downloads.html&quot;&gt;mGBA emulator&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mgba.io&#x2F;downloads.html&quot;&gt;mgba.io&#x2F;downloads.html&lt;&#x2F;a&gt;)
as it is the recommended emulator by the crate authors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;project-creation-auto&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#project-creation-auto&quot;&gt;Project Creation (automatic)&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The following section of the tutorial covers setting up the Rust project with the proper configuration.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to skip manual file creation, you can clone a starter copy of this project using the command below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; clone&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; starter&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;undecidedapollo&#x2F;gba-tutorial.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;callout callout--tip&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&#x2F;&gt;&lt;line x1=&quot;12&quot; x2=&quot;12&quot; y1=&quot;8&quot; y2=&quot;12&quot;&#x2F;&gt;&lt;line x1=&quot;12&quot; x2=&quot;12&quot; y1=&quot;16&quot; y2=&quot;16.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;After cloning, you will need to edit your &lt;code&gt;.cargo&#x2F;config.toml&lt;&#x2F;code&gt; to point to your &lt;code&gt;mGBA&lt;&#x2F;code&gt; emulator downloaded above, it is different for each Operating System.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;#cargo-config&quot;&gt;More info in &quot;Cargo Config&quot; below&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;


&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Once cloned and &lt;code&gt;.cargo&#x2F;config.toml&lt;&#x2F;code&gt; is updated you should be able to run &lt;code&gt;cargo run&lt;&#x2F;code&gt; and it will start &lt;code&gt;mGBA&lt;&#x2F;code&gt; and show a blank, white screen.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#doing-something&quot;&gt;Click here to skip ahead to &quot;Doing Something&quot;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;project-creation-manual&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#project-creation-manual&quot;&gt;Project Creation (manual)&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;With everything installed we can use &lt;code&gt;cargo&lt;&#x2F;code&gt; to create a new &lt;code&gt;binary&lt;&#x2F;code&gt; project which we will use as the foundation for building our GBA game.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-bin&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; gba-tutorial&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can now &lt;code&gt;cd gba-tutorial&lt;&#x2F;code&gt; into our project and begin setting it up for GBA development.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;nightly-rust&quot;&gt;Nightly Rust&lt;&#x2F;h4&gt;
&lt;p&gt;GBA development with Rust requires us to use the nightly compiler. To tell Rust to always use the nightly compiler for our project we start by setting up a &lt;code&gt;rust-toolchain.toml&lt;&#x2F;code&gt; file in the root of our project.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;toolchain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;channel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nightly&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;components&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rust-src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you are like me and like to pin your versions, you can specify a specific nightly version here instead like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;toolchain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;channel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nightly-2026-05-09&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;components&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rust-src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;cargo-config&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#cargo-config&quot;&gt;Cargo Config&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;First, we need to tell cargo more about this project and how to build it. We start by creating a directory called &lt;code&gt;.cargo&lt;&#x2F;code&gt; and creating a file inside of it called &lt;code&gt;config.toml&lt;&#x2F;code&gt; (full path: &lt;code&gt;.cargo&#x2F;config.toml&lt;&#x2F;code&gt;). You will need to modify some values in the file. I&#x27;ve highlighted them below and the callout below has more information.&lt;&#x2F;p&gt;
&lt;div class=&quot;callout callout--warning&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3&quot;&#x2F;&gt;&lt;path d=&quot;M12 9v4&quot;&#x2F;&gt;&lt;path d=&quot;M12 17h.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;The runner variable needs to point to the mGBA executable somewhere on your system. Depending on how you installed it (download, package manager, etc.) you will need to update the runner to point at the executable.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve included a few common configurations below that you can uncomment (remove the &lt;code&gt;#&lt;&#x2F;code&gt; symbol before the &lt;code&gt;runner = &quot;MGBA_LOCATION&quot;&lt;&#x2F;code&gt; of your choice).&lt;&#x2F;p&gt;


&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;build&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;thumbv4t-none-eabi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Specify the cpu &#x2F; system architecture we are targeting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;unstable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;build-std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;core&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Specify we only want core&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;target&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;thumbv4t-none-eabi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; UNCOMMENT THE RUNNER FOR YOUR PLATFORM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Windows: Point at the installed exe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; runner = [&amp;quot;C:\\Program Files\\mGBA\\mGBA.exe&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; MacOS: Point at the executable inside the .app file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; runner = [&amp;quot;&#x2F;Applications&#x2F;mGBA.app&#x2F;Contents&#x2F;MacOS&#x2F;mGBA&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Linux: if installed with a package manager&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; runner = [&amp;quot;mgba-qt&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;rustflags&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-Clinker=arm-none-eabi-ld&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; uses the ARM linker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-Clink-arg=-Tlinker.ld&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; sets the link script&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;download-linker-script&quot;&gt;Download Linker Script&lt;&#x2F;h4&gt;
&lt;p&gt;We need a link script to tell the linker how to properly structure our executable. Thankfully the &lt;code&gt;gba&lt;&#x2F;code&gt; crate authors provide us with one.&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-console&#x2F;gba&#x2F;blob&#x2F;main&#x2F;linker_scripts&#x2F;mono_boot.ld&quot;&gt;Linker File&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-console&#x2F;gba&#x2F;blob&#x2F;main&#x2F;linker_scripts&#x2F;mono_boot.ld&quot;&gt;github.com&#x2F;rust-console&#x2F;gba&#x2F;blob&#x2F;main&#x2F;linker_scripts&#x2F;mono_boot.ld&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;Download or copy the file and save it to &lt;code&gt;linker.ld&lt;&#x2F;code&gt; inside of your project.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;add-the-gba-crate&quot;&gt;Add the GBA Crate&lt;&#x2F;h4&gt;
&lt;p&gt;Add the gba crate to the project, we will use version 0.15 which is the latest at the time this tutorial was written.&lt;&#x2F;p&gt;
&lt;p&gt;You can use cargo to add the crate:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; gba@0.15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At the end, your &lt;code&gt;Cargo.toml&lt;&#x2F;code&gt; should look like the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;package&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;gba-tutorial&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0.1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;edition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2024&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;dependencies&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;gba&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0.15&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;create-our-first-executable&quot;&gt;Create Our First Executable&lt;&#x2F;h4&gt;
&lt;p&gt;Lastly, we can copy a modified version of the starter function definition from the &lt;code&gt;gba&lt;&#x2F;code&gt; crate documentation which sets up a &lt;code&gt;no-std&lt;&#x2F;code&gt; compatible executable file. It is barebones and won&#x27;t do anything, but we will be able to run it.&lt;&#x2F;p&gt;
&lt;p&gt;Update your existing &lt;code&gt;src&#x2F;main.rs&lt;&#x2F;code&gt; file (created above with &lt;code&gt;cargo new&lt;&#x2F;code&gt;) to have the following contents:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;no_std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;no_main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt; gba&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;prelude&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;panic_handler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; panic_handler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;core&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;panic&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;PanicInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;no_mangle&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;optional-vscode-configuration&quot;&gt;(Optional) VSCode Configuration&lt;&#x2F;h4&gt;
&lt;p&gt;If you are using rust-analyzer inside VSCode, you may notice it giving you warnings from the above code changes. Since we are building a rom that doesn&#x27;t use std and uses a custom architecture we need to tell VSCode about it. To do so, create a folder called &lt;code&gt;.vscode&lt;&#x2F;code&gt; and create a file named &lt;code&gt;settings.json&lt;&#x2F;code&gt; and put the following (full path: &lt;code&gt;.vscode&#x2F;settings.json&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;rust-analyzer.cargo.target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;thumbv4t-none-eabi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;rust-analyzer.cargo.buildScripts.overrideCommand&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;check&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;--target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;thumbv4t-none-eabi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;build-std=core,alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;--message-format=json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;rust-analyzer.check.overrideCommand&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;check&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;--target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;thumbv4t-none-eabi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;build-std=core,alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;--message-format=json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;rust-analyzer.check.allTargets&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-json&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;rust-analyzer.cargo.extraEnv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;RUSTFLAGS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-Clink-arg=-Tlinker.ld&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;run-our-rom-first-time&quot;&gt;Run our ROM (first time)&lt;&#x2F;h4&gt;
&lt;p&gt;At this point we can run our rom!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div class=&quot;callout callout--info&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&#x2F;&gt;&lt;path d=&quot;M12 16v-4&quot;&#x2F;&gt;&lt;path d=&quot;M12 8h.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;We use &lt;code&gt;--release&lt;&#x2F;code&gt; mode because the Rust code generated in debug mode is not optimized and the ARM processor on the GBA too slow to run the code at reasonable rate.&lt;&#x2F;p&gt;
&lt;p&gt;Later when we draw a rectangle, try running in debug mode (without the release flag) and watch how slowly it fills the screen.&lt;&#x2F;p&gt;


&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;While it doesn&#x27;t do anything but display a white screen, it does show that we can build a Rust program into a Game Boy Advance ROM.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;assets&#x2F;white_bg.png&quot; alt=&quot;mGBA emulator showing a white background&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;doing-something&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#doing-something&quot;&gt;Doing Something&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now that we have a functioning starter project, let&#x27;s try to get something on the screen of the Game Boy.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;game-boy-advance-video-background&quot;&gt;Game Boy Advance Video Background&lt;&#x2F;h3&gt;
&lt;p&gt;The Game Boy Advance has a 240 (horizontal) by 160 (vertical) color screen which can be driven by a variety of video modes. Each video mode offers a different combination of features for how you can control the screen. The Game Boy has a few different features we can leverage to show things on the screen.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;high-level-feature-overview&quot;&gt;High-level feature overview:&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Background Features&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bitmap Backgrounds&lt;&#x2F;strong&gt; Control individual pixels on the screen, slow&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Text Background&lt;&#x2F;strong&gt; Traditional tile based layouts, tiles are 8x8 groups of pixels which can be placed on the screen in a grid format.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Affine Background&lt;&#x2F;strong&gt; Advanced backgrounds similar to tile based layouts but you can perform operations on the background as a whole, such as zoom, rotation, and shear.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Foreground Features&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Objects &#x2F; Sprites&lt;&#x2F;strong&gt; 128 sprite objects that you can control and move around on the screen. By default 8x8 but size can be changed. Optional affine transformations on a per-obj basis with zoom, rotation, and shear.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;callout callout--info&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&#x2F;&gt;&lt;path d=&quot;M12 16v-4&quot;&#x2F;&gt;&lt;path d=&quot;M12 8h.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;For more information on how data is drawn to the screen and video modes, check out:&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coranac.com&#x2F;tonc&#x2F;text&#x2F;video.htm&quot;&gt;Tonc&#x27;s &quot;Introduction to GBA Graphics&quot;.&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coranac.com&#x2F;tonc&#x2F;text&#x2F;video.htm&quot;&gt;coranac.com&#x2F;tonc&#x2F;text&#x2F;video.htm&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.patater.com&#x2F;gbaguy&#x2F;gba&#x2F;ch5.htm&quot;&gt;GBA Video Modes&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.patater.com&#x2F;gbaguy&#x2F;gba&#x2F;ch5.htm&quot;&gt;patater.com&#x2F;gbaguy&#x2F;gba&#x2F;ch5.htm&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;


&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;draw-a-pixel-on-the-screen&quot;&gt;Draw a pixel on the screen&lt;&#x2F;h3&gt;
&lt;p&gt;We are going to use video mode 3 as it allows us to write direct pixel data to VRAM and have it display on the screen. While bitmap is the most versatile way to display pixels on the screen, it is slow and time consuming for the CPU to draw every pixel on the screen. We will use it to get started then switch to using tiles &#x2F; objects later on.&lt;&#x2F;p&gt;
&lt;p&gt;First, we tell the [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;0.15.0&#x2F;gba&#x2F;video&#x2F;struct.DisplayControl.html&quot;&gt;DISPCNT (DisplayControl)&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;0.15.0&#x2F;gba&#x2F;video&#x2F;struct.DisplayControl.html&quot;&gt;docs.rs&#x2F;gba&#x2F;0.15.0&#x2F;gba&#x2F;video&#x2F;struct.DisplayControl.html&lt;&#x2F;a&gt;)
that we want to use Video Mode 3 and to turn on background 2 (there are four backgrounds, Video Mode 3 uses background 2 to show the bitmap).&lt;&#x2F;p&gt;
&lt;div class=&quot;callout callout--info&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&#x2F;&gt;&lt;path d=&quot;M12 16v-4&quot;&#x2F;&gt;&lt;path d=&quot;M12 8h.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;You can read more about bitmap modes at:&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coranac.com&#x2F;tonc&#x2F;text&#x2F;bitmaps.htm&quot;&gt;Tonc&#x27;s &quot;The Bitmap modes (mode 3, 4, 5)&quot;&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coranac.com&#x2F;tonc&#x2F;text&#x2F;bitmaps.htm&quot;&gt;coranac.com&#x2F;tonc&#x2F;text&#x2F;bitmaps.htm&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;


&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Next we will draw a single, blue pixel on the screen at column=10, row = 20 (x=10, y=20)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;no_mangle&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;    DISPCNT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;        DisplayControl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;with_video_mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;VideoMode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;_3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;with_show_bg2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;    VIDEO3_VRAM&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;Color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;BLUE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you run this you should see a small blue dot on a black screen:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;assets&#x2F;blue_pixel.png&quot; alt=&quot;A blue pixel at (10, 20)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lets-draw-more&quot;&gt;Lets draw more!&lt;&#x2F;h3&gt;
&lt;p&gt;Drawing a pixel is fun, but we can go a step further. Let&#x27;s draw a box!&lt;&#x2F;p&gt;
&lt;p&gt;We will add a nested &lt;code&gt;for&lt;&#x2F;code&gt; loop to our main and get it to draw a large rectangle.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; start_col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; start_row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; end_col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; start_col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 120&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; end_row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; start_row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; start_row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;end_row&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; start_col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;end_col&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;            VIDEO3_VRAM&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;col&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;Color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;BLUE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After running the ROM:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A large, blue, horizontal rectangle enters the chat&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;assets&#x2F;blue_rectangle.png&quot; alt=&quot;A blue, filled-in rectangle at (10, 20) of width 120 and height 30&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;drawing-over-time&quot;&gt;Drawing Over Time&lt;&#x2F;h3&gt;
&lt;p&gt;Drawing on the GBA doesn&#x27;t have to happen all at once. The screen on the Game Boy updates at 60 frames per second (fps) and in between those frames we can make as many changes as we&#x27;d like to the screen and it will draw the changes on the next frame.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of a loop where we start all at once, we will draw a new pixel each frame to the screen and watch as it updates the screen each frame.&lt;&#x2F;p&gt;
&lt;p&gt;First, we will need to instruct the Game Boy to notify us when a VBlank occurs. A VBlank is the moment after the graphics unit has finished drawing the screen and gives us a moment to modify the screen parameters &#x2F; Video RAM without it interfering with the display.&lt;&#x2F;p&gt;
&lt;div class=&quot;callout callout--info&quot;&gt;
&lt;span class=&quot;callout__icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&#x2F;&gt;&lt;path d=&quot;M12 16v-4&quot;&#x2F;&gt;&lt;path d=&quot;M12 8h.01&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;span&gt;
&lt;div class=&quot;callout__body&quot;&gt;

&lt;p&gt;You can read more about VBlank at:&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coranac.com&#x2F;tonc&#x2F;text&#x2F;video.htm&quot;&gt;Tonc&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.coranac.com&#x2F;tonc&#x2F;text&#x2F;video.htm&quot;&gt;coranac.com&#x2F;tonc&#x2F;text&#x2F;video.htm&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;


&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;To do so we will have to wire up a few new things to tell it that we are interested in knowing when a VBlank occurs. Start by replacing our &lt;code&gt;main.rs&lt;&#x2F;code&gt; with the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;no_std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;no_main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt; gba&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;prelude&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;panic_handler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; panic_handler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;core&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;panic&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;PanicInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-attribute z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute z-rust&quot;&gt;no_mangle&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;    DISPSTAT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;DisplayStatus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;with_irq_vblank&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;    IE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;IrqBits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;VBLANK&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;    IME&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;    DISPCNT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;        DisplayControl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;with_video_mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;VideoMode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;_3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;with_show_bg2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        VBlankIntrWait&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next we will update the &lt;code&gt;fn main()&lt;&#x2F;code&gt; loop to keep track of where we are drawing and to draw one pixel per VBlank:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; SCREEN_WIDTH&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 240&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; SCREEN_HEIGHT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 160&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        VBlankIntrWait&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;        VIDEO3_VRAM&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;col&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;Color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;BLUE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; SCREEN_WIDTH&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; SCREEN_HEIGHT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l z-hl&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running this we will see the screen slowly start to fill with blue. 60 frames per second is a lot but doing one pixel at a time at a width of 240 pixels it takes exactly 4 seconds per line, for all 160 vertical lines you would have to wait over 10 minutes for the whole screen to fill up.&lt;&#x2F;p&gt;
&lt;video autoplay controls loop muted playsinline preload=&quot;auto&quot; aria-label=&quot;A blue dot slowly fills in the screen, starting from the top-left and working its way across row-by-row&quot;&gt;
&lt;source src=&quot;assets&amp;#x2F;blue_line.mp4&quot; type=&quot;video&#x2F;mp4&quot;&gt;
&lt;&#x2F;video&gt;
&lt;h2 id=&quot;wrap-up&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jonahnestrick.com&#x2F;blog&#x2F;rust-gba-tutorial-1&#x2F;#wrap-up&quot;&gt;Wrap Up&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;With that we have built a Rust program that compiles to a Game Boy Advance ROM which can draw to the screen. In future tutorials we will cover how to use other background modes, how to draw objects &#x2F; sprites to the screen, and how to get input from the user.&lt;&#x2F;p&gt;
&lt;p&gt;In the meantime I highly recommend reading [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kylehalladay.com&#x2F;gba.html&quot;&gt;Kyle Halladay - &quot;GBA Tutorial&quot;&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kylehalladay.com&#x2F;gba.html&quot;&gt;kylehalladay.com&#x2F;gba.html&lt;&#x2F;a&gt;)
as he covers these topics in C++. Many of the code examples you can bring over to Rust with some minor translation.&lt;&#x2F;p&gt;
&lt;p&gt;Also take a look at the docs for the [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;&quot;&gt;gba&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;&quot;&gt;docs.rs&#x2F;gba&#x2F;latest&#x2F;gba&#x2F;&lt;&#x2F;a&gt;)
crate, there is a lot of useful information inside. The [&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-console&#x2F;gba&quot;&gt;repo&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-console&#x2F;gba&quot;&gt;github.com&#x2F;rust-console&#x2F;gba&lt;&#x2F;a&gt;)
also has an &lt;code&gt;&#x2F;examples&lt;&#x2F;code&gt; folder which shows you how to do various things on the gba (note, you may have to make some updates since we are using the 2024 edition of Rust).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The full source code for the above tutorial can be found here:&lt;&#x2F;p&gt;
&lt;p&gt;[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;undecidedapollo&#x2F;gba-tutorial&#x2F;tree&#x2F;lesson-01&quot;&gt;Lesson 01&lt;&#x2F;a&gt;](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;undecidedapollo&#x2F;gba-tutorial&#x2F;tree&#x2F;lesson-01&quot;&gt;github.com&#x2F;undecidedapollo&#x2F;gba-tutorial&#x2F;tree&#x2F;lesson-01&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I&#x27;ll update this spot with links as more tutorials and related articles are created. If you see nothing, that means you are up to date 😄&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hello, World</title>
        <published>2026-05-13T15:00:00+00:00</published>
        <updated>2026-05-13T15:00:00+00:00</updated>
        
        <author>
          <name>
            
              Jonah Nestrick &lt;jonah.nestrick@gmail.com&gt;
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://jonahnestrick.com/blog/hello-world/"/>
        <id>https://jonahnestrick.com/blog/hello-world/</id>
        
        <content type="html" xml:base="https://jonahnestrick.com/blog/hello-world/">&lt;p&gt;The first thing you do when learning a new language is write a simple program.&lt;&#x2F;p&gt;
&lt;p&gt;The choice you are taught is &quot;Hello, World&quot;. A small program that shows the text &quot;Hello, World&quot; to the user.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m sure there are better things I could write about in a personal blog but this will have to do:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-macro z-rust&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Hello, world!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Hello, world!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
</feed>
