<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>SkyLyrac</title>
        <link>https://skylyrac.net/</link>
        <description>Recent content on SkyLyrac</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <copyright>Antonio Niño Díaz</copyright>
        <lastBuildDate>Wed, 14 Jan 2026 01:47:00 +0000</lastBuildDate><atom:link href="https://skylyrac.net/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>BlocksDS SDK Version 1.1.0</title>
        <link>https://skylyrac.net/p/2024-05-15-blocksds-sdk-version-1-1-0/</link>
        <pubDate>Wed, 15 May 2024 02:19:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2024-05-15-blocksds-sdk-version-1-1-0/</guid>
        <description>&lt;p&gt;It&amp;rsquo;s been over a year since the first release of &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/sdk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;BlocksDS&lt;/a&gt;,
and over half year since &lt;a class=&#34;link&#34; href=&#34;../2023-08-18-blocksds-sdk&#34; &gt;this blog post&lt;/a&gt;, which was
written after version 0.8.1 was released. The current version is 1.1.0, which
means it&amp;rsquo;s time to write a new post with the current state of BlocksDS!&lt;/p&gt;
&lt;p&gt;First of all, check this up-to-date &lt;a class=&#34;link&#34; href=&#34;https://blocksds.skylyrac.net/docs/introduction&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;introduction&lt;/a&gt;
if you have never heard of BlocksDS. Feel free to skip it if you are already
familiar with it! In short, it is an actively maintained SDK to develop
applications for the DS in C or C++.&lt;/p&gt;
&lt;p&gt;There are too many changes between versions 1.1.0 and 0.8.1 to list them here.
You can check the &lt;a class=&#34;link&#34; href=&#34;https://blocksds.skylyrac.net/docs/changelog&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;changelog&lt;/a&gt;
for more details, but this is a list of the most important changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;NitroFS has been fully reimplemented by &lt;a class=&#34;link&#34; href=&#34;https://asie.pl&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;asie&lt;/a&gt;, which
increased filesystem performance by orders of magnitude. The previous system
(NitroFAT) was a workaround implemented by me which required two levels of FAT
filesystem access, and that was very slow.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There is experimental and preliminary support for the Teak DSP of the DSi. It
isn&amp;rsquo;t ready to be used by most people, but it&amp;rsquo;s in a good enough state that
developers can use the current toolchain and libraries to make incremental
improvements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A new API has been added to use Slot-2 peripherals like RAM expansion packs,
rumble, gyroscopes and tilt sensors.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The default Makefiles have been simplified and they now use compiler-provided
&lt;code&gt;.specs&lt;/code&gt; files (which will make it easier to keep up-to-date with potential
compiler and linker flags changes).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A race condition between &lt;code&gt;scanKeys()&lt;/code&gt; and &lt;code&gt;touchRead()&lt;/code&gt; has been fixed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The RTC interrupt is no longer used to update the RTC time. Most emulators
didn&amp;rsquo;t support it, and it wasn&amp;rsquo;t supported by the 3DS in DS/DSi mode.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The documentation of BlocksDS and all its libraries has been dramatically
improved and it is now available online: &lt;a class=&#34;link&#34; href=&#34;https://blocksds.skylyrac.net&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://blocksds.skylyrac.net&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lots and lots of examples have been added.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some minor changes that are also significant:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There are new helper functions to set and get the current RTC time in a
convenient way. The old setter function didn&amp;rsquo;t work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;glTexImage2D()&lt;/code&gt; now accepts sizes in pixels as well as &lt;code&gt;GL_TEX_SIZE_ENUM&lt;/code&gt;
values. This is something that has always bothered me, the requirement to use
the enumeration values always made using this function very awkward.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There have been some improvements to &lt;code&gt;grit&lt;/code&gt; to improve the &lt;code&gt;grf&lt;/code&gt; format.
&lt;code&gt;libnds&lt;/code&gt; now has functions to read graphics from &lt;code&gt;grf&lt;/code&gt; files, and they are
used in some examples.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;dlditool&lt;/code&gt; has been replaced by &lt;code&gt;dldipatch&lt;/code&gt;, which is less buggy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some libc locking functions (&lt;code&gt;_retarget_lock_*()&lt;/code&gt;) have been implemented
to allow libc functions to work in a multithreaded environment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The following libc functions have been implemented: &lt;code&gt;realpath()&lt;/code&gt;, &lt;code&gt;utime()&lt;/code&gt;,
&lt;code&gt;utimes()&lt;/code&gt;, &lt;code&gt;scandir()&lt;/code&gt;, &lt;code&gt;alphasort()&lt;/code&gt;, &lt;code&gt;versionsort()&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Added &lt;code&gt;nitroFSOpenById()&lt;/code&gt; and &lt;code&gt;nitroFSFopenById()&lt;/code&gt; functions, allowing opening
files directly without paying the cost of a directory lookup.  Accordingly,
NitroFS file systems which contain a FAT table but no FNT table can now be
opened.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There is now a function to get the name of the default drive (&lt;code&gt;sd:&lt;/code&gt; for DSi,
&lt;code&gt;fat:&lt;/code&gt; for DS).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The value of the RAM size field in &lt;code&gt;REG_SCFG_EXT&lt;/code&gt; in the ARM9 is now set to 16
MB or 32 MB instead of being fixed to 32 MB even in retail DSi units.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Dual screen 3D on the NDS</title>
        <link>https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/</link>
        <pubDate>Thu, 12 Oct 2023 21:36:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/</guid>
        <description>&lt;p&gt;The Nintendo DS has a GPU with a 3D engine that supports a surprising amount of
features. Normally it can only be used to display 3D graphics on one screen, but
it is possible to display 3D on both screens by using a special video capture
circuit.&lt;/p&gt;
&lt;p&gt;This technique isn&amp;rsquo;t straightforward. The video hardware of the NDS is very
flexible, and there are several ways to achieve 3D graphics on both screens.&lt;/p&gt;
&lt;p&gt;Over the last few weeks I&amp;rsquo;ve been working on improving the dual screen 3D
support of &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/nitro-engine&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Nitro Engine&lt;/a&gt;. It has
never been particularly reliable (when the framerate drops, the same output is
shown in both screens), and it is important that it is reliable because games
that use dual 3D are also likely to push the 3D hardware to the limit, and to
have framerate drops every now and then.&lt;/p&gt;
&lt;p&gt;This post is a very detailed explanation of how I&amp;rsquo;ve implemented things in Nitro
Engine. I&amp;rsquo;ve explained the reasons why each mode may be used, as well as their
limitations.&lt;/p&gt;
&lt;p&gt;If this post is too long for you to read, just use &lt;code&gt;NE_InitDual3D_DMA()&lt;/code&gt; in
your games and skip the read! However, feel free to keep reading if you care
about the details about how all of it is implemented.&lt;/p&gt;
&lt;p&gt;Something that applies to all the systems is that the 3D engine can only send
the output to one of the two screens during a specific frame. Any dual 3D setup
implies saving that 3D engine output to VRAM and displaying it on the other
screen during the following frame. Essentially, the main graphics engine and sub
graphics engine need to switch from one screen to the other after every frame.&lt;/p&gt;
&lt;p&gt;A huge thanks to mtheal and JustBurn for the
&lt;a class=&#34;link&#34; href=&#34;https://mtheall.com/banks.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NDS Homebrew VRAM Banks Selector&lt;/a&gt; and the
&lt;a class=&#34;link&#34; href=&#34;https://mtheall.com/vram.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NDS Homebrew VRAM BG Allocation Conflict Viewer&lt;/a&gt;,
tools that made my life a lot easier when working on this. Check them out, and
their source code on &lt;a class=&#34;link&#34; href=&#34;https://github.com/mtheall/vram&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;1-memory-usage&#34;&gt;1. Memory usage
&lt;/h2&gt;&lt;p&gt;First of all, it is important to mention that dual 3D comes at a big cost. It is
impossible to have dual 3D without using two of the main VRAM banks (A, B, C and
D) as framebuffers. This means that half of the memory that the developer can
allocate for textures won&amp;rsquo;t be available at all. There are two main things to
consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Compressed textures: They are the most efficient way to have textures in VRAM,
and they need to be stored in a combination of VRAM A and B or VRAM B and C.
All the dual 3D modes of Nitro Engine leave VRAM banks A and B available for
textures, so compressed textures can be used.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clear bitmap: It is possible to store a bitmap with its own depth map (sort of
a Z-buffer for the bitmap) in VRAM banks C and D. While this is an interesting
feature, it isn&amp;rsquo;t used nearly enough to worry about it, as it is a very
inefficient way to use VRAM (it requires 50% of the texture VRAM). In dual 3D
mode the developer can only use only 50% of the total memory available for
textures, so clear bitmaps aren&amp;rsquo;t useful.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a comparative table of all modes supported by Nitro Engine and how the
different VRAM banks are used. Each mode will be explained in each own section:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;Single screen 3D&lt;/th&gt;
          &lt;th&gt;Dual screen 3D&lt;/th&gt;
          &lt;th&gt;Dual 3D FB&lt;/th&gt;
          &lt;th&gt;Dual 3D DMA&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM A&lt;/td&gt;
          &lt;td&gt;3D textures [1]&lt;/td&gt;
          &lt;td&gt;3D textures [1]&lt;/td&gt;
          &lt;td&gt;3D textures [1]&lt;/td&gt;
          &lt;td&gt;3D textures [1]&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM B&lt;/td&gt;
          &lt;td&gt;[1]&lt;/td&gt;
          &lt;td&gt;[1]&lt;/td&gt;
          &lt;td&gt;[1]&lt;/td&gt;
          &lt;td&gt;[1]&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM C&lt;/td&gt;
          &lt;td&gt;[1]&lt;/td&gt;
          &lt;td&gt;Framebuffer 1&lt;/td&gt;
          &lt;td&gt;Framebuffer 1&lt;/td&gt;
          &lt;td&gt;Framebuffer 1 + Debug console [3]&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM D&lt;/td&gt;
          &lt;td&gt;[1]&lt;/td&gt;
          &lt;td&gt;Framebuffer 2&lt;/td&gt;
          &lt;td&gt;Framebuffer 2&lt;/td&gt;
          &lt;td&gt;Framebuffer 2&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM E&lt;/td&gt;
          &lt;td&gt;3D palettes&lt;/td&gt;
          &lt;td&gt;3D palettes&lt;/td&gt;
          &lt;td&gt;3D palettes&lt;/td&gt;
          &lt;td&gt;3D palettes&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM F&lt;/td&gt;
          &lt;td&gt;Debug console&lt;/td&gt;
          &lt;td&gt;Debug console&lt;/td&gt;
          &lt;td&gt;[2]&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM G&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM H&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;VRAM I&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;Pseudo FB + Debug console [3]&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note [1]: It is possible to tell Nitro Engine to not use specific VRAM banks out
of A, B, C and D. This is useful when using Nitro Engine at the same time as
some other library like NFlib. It is also possible to tell Nitro Engine to not
use VRAM banks A or B in dual 3D mode, but this isn&amp;rsquo;t normally useful.&lt;/p&gt;
&lt;p&gt;Note [2]: The debug console isn&amp;rsquo;t supported in this mode.&lt;/p&gt;
&lt;p&gt;Note [3]: The debug console is replicated in both VRAM I and the space of VRAM C
that isn&amp;rsquo;t used by the video capture. This also means that enabling the debug
console doesn&amp;rsquo;t require any additional memory banks, unlike in other modes
(however, it uses a bit of CPU). More details below.&lt;/p&gt;
&lt;h2 id=&#34;2-the-capture-unit&#34;&gt;2. The capture unit
&lt;/h2&gt;&lt;p&gt;The capture unit allows you to capture the output of the main graphics engine.
It is possible to capture the 3D output by itself before any layering effect,
or the combined 2D+3D output. This last mode is useful if you want to display a
2D background on top of the 3D output, and then display that on the other
screen. In Nitro Engine this is used to display the debug console on top of the
3D output.&lt;/p&gt;
&lt;p&gt;It is a very flexible unit. It lets you select the size of the capture, the VRAM
bank used as destination (A, B, C or D), and even an offset for the destination
bank (for example, if you want to start saving the captured output after the
first fourth of the bank). Check &lt;a class=&#34;link&#34; href=&#34;https://problemkaputt.de/gbatek.htm#dsvideodisplaysystemblockdiagram&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBATEK&lt;/a&gt;
for more information.&lt;/p&gt;
&lt;p&gt;The only problem with this unit is that the destination bank must be mapped to
the CPU (LCD mode if you are using libnds). This restricts a lot what you can
do. There is a mode that lets you use the contents in VRAM as a framebuffer even
when it is mapped to the CPU, but it doesn&amp;rsquo;t let you layer anything on top of
it.&lt;/p&gt;
&lt;h2 id=&#34;3-single-screen-3d-mode&#34;&gt;3. Single screen 3D mode
&lt;/h2&gt;&lt;p&gt;Before talking about dual 3D, let&amp;rsquo;s start with single screen 3D, which is easier
to explain. VRAM banks are used like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM A, B, C, D: Textures.&lt;/li&gt;
&lt;li&gt;VRAM E: Texture palettes.&lt;/li&gt;
&lt;li&gt;VRAM F: Debug console (if it is enabled).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output in the main screen is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Layer 0: 3D output&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the debug console is enabled, it changes a bit. The priorities of layers 0
and 1 are swapped so that the debug console appears on top of the 3D output.
VRAM F is setup as main engine background memory, and:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Layer 0: 3D output, priority 1.&lt;/li&gt;
&lt;li&gt;Layer 1: Debug console, priority 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;4-dual-screen-3d-mode&#34;&gt;4. Dual screen 3D mode
&lt;/h2&gt;&lt;p&gt;The source code &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/nitro-engine/src/commit/8c323c7e2c29bf0b52951ac2756139026f09f269/source/NEGeneral.c#L608&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;for regular dual 3D mode is here&lt;/a&gt;
and &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/nitro-engine/src/commit/8c323c7e2c29bf0b52951ac2756139026f09f269/source/NEGeneral.c#L493&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the source code for the console initialization is here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is the traditional way to handle dual 3D, and it is used in multiple
examples that can be found &lt;a class=&#34;link&#34; href=&#34;https://github.com/devkitPro/nds-examples/blob/6afa09b2054c9f47685514c32873b3905721c9ee/Graphics/3D/3D_Both_Screens/source/template.c&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;online&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;VRAM banks are used like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM A, B: Textures.&lt;/li&gt;
&lt;li&gt;VRAM C, D: Framebuffers.&lt;/li&gt;
&lt;li&gt;VRAM E: Texture palettes.&lt;/li&gt;
&lt;li&gt;VRAM F: Debug console of main screen (if it is enabled).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Odd frames:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM C is mapped as sub engine background. It holds a 16 bit framebuffer.&lt;/li&gt;
&lt;li&gt;VRAM D is mapped to the CPU.&lt;/li&gt;
&lt;li&gt;VRAM F is mapped as main engine background. It holds the debug console.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output of the main screen is the combined output of the 3D engine and the
main 2D engine, which displays the debug console.&lt;/p&gt;
&lt;p&gt;The output of the sub screen is the background stored in VRAM C.&lt;/p&gt;
&lt;p&gt;The capture unit takes as input the same output as the main screen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Even frames:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM C is mapped to the CPU.&lt;/li&gt;
&lt;li&gt;VRAM D is mapped as sub engine sprites. It holds a 16 bit framebuffer.&lt;/li&gt;
&lt;li&gt;VRAM F isn&amp;rsquo;t used.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output of the main screen is the combined output of the 3D engine and the
main 2D engine, which isn&amp;rsquo;t showing anything right now.&lt;/p&gt;
&lt;p&gt;The output of the sub screen is the background stored in VRAM D. However, it
isn&amp;rsquo;t possible to use VRAM D as sub engine background memory, so a grid of 64x64
sprites is setup so that they display the contents of VRAM D as a 256x192 image.&lt;/p&gt;
&lt;p&gt;The capture unit takes as input the same output as the main screen.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d.png&#34;
	width=&#34;643&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d_hu_eba2d0b391b8a6ca.png 480w, https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d_hu_75a2f66381543a44.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;114&#34;
		data-flex-basis=&#34;274px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The latency of the 3D rendered image is zero. It is directly displayed on the
screen without any delay.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The screen effects based on changing the horizontal scroll every scanline
work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The debug console is supported.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No CPU or DMA processing is needed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;All 256x192 pixels of the screens are used.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If the framerate ever drops below 60 FPS, the same 3D output will be displayed
on both screens until the next frame is rendered. It can happen when loading
assets at runtime, for example. This happens because only one frame is
actually displayed from a framebuffer. The other one depends on the actual
output of the 3D graphics engine.&lt;/p&gt;
&lt;p&gt;While screen A is displayed from a framebuffer, the framebuffer of screen B is
capturing the output of the new screen B. During the next frame, if screen A
can&amp;rsquo;t be drawn, the framebuffer of screen B will be displayed from a
framebuffer while the 3D engine still displays the previous screen, which is
screen B.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The textures and palettes of the NDS use 15 bit colors, that is, they use 5
bits per component (R, G, B). However, the LCD screen of the NDS uses 6 bits
per component. Normally the least significant bit isn&amp;rsquo;t used, but it can be
used if two poligons are blended together, for example.&lt;/p&gt;
&lt;p&gt;This is a problem because the video capture unit doesn&amp;rsquo;t capture the 6 bits.
If the output switches between actual 3D output and captured 3D output the
user may notice that the image changes slightly between frames.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The debug console requires an additional VRAM bank, even if it&amp;rsquo;s one of the
small ones.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I discourage you from using this mode. It&amp;rsquo;s too easy to fall below 60 FPS and
hit the issue where both screens will show the same output.&lt;/p&gt;
&lt;h2 id=&#34;5-dual-screen-3d-fb-mode&#34;&gt;5. Dual screen 3D FB mode
&lt;/h2&gt;&lt;p&gt;The source code &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/nitro-engine/src/commit/8c323c7e2c29bf0b52951ac2756139026f09f269/source/NEGeneral.c#L670&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;for dual 3D FB mode is here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is another well-known way to handle dual 3D, but it prevents you from using
the 2D engine in the screen that is being updated in that frame. This prevents
us from displaying a debug console in one screen because it would only be
displayed there half of the frames.&lt;/p&gt;
&lt;p&gt;It is named after the &lt;code&gt;MODE_FB2&lt;/code&gt; and &lt;code&gt;MODE_FB3&lt;/code&gt; constants of
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/libnds/src/commit/21ad6a51f5ffff00fa47e9a17f8547a46036933f/include/nds/arm9/video.h#L497-L500&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;libnds&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;VRAM banks are used like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM A, B: Textures.&lt;/li&gt;
&lt;li&gt;VRAM C, D: Framebuffers.&lt;/li&gt;
&lt;li&gt;VRAM E: Texture palettes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Odd frames:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM C is mapped as sub engine background. It holds a 16 bit framebuffer.&lt;/li&gt;
&lt;li&gt;VRAM D is mapped to the CPU.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The main engine is setup in direct VRAM display mode, so the output of the main
screen is the contents of VRAM D.&lt;/p&gt;
&lt;p&gt;The output of the sub screen is the background stored in VRAM C.&lt;/p&gt;
&lt;p&gt;The capture unit takes as input the 3D output directly, and it saved it to VRAM
D, which can be accessed by the capture hardware because it&amp;rsquo;s mapped to the CPU.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Even frames:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM C is mapped to the CPU.&lt;/li&gt;
&lt;li&gt;VRAM D is mapped as sub engine sprites. It holds a 16 bit framebuffer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The main engine is setup in direct VRAM display mode, so the output of the main
screen is the contents of VRAM C.&lt;/p&gt;
&lt;p&gt;The output of the sub screen is the background stored in VRAM D. However, it
isn&amp;rsquo;t possible to use VRAM D as sub engine background memory, so a grid of 64x64
sprites is setup so that they display the contents of VRAM D as a 256x192 image.&lt;/p&gt;
&lt;p&gt;The capture unit takes as input the 3D output directly, and it saved it to VRAM
C, which can be accessed by the capture hardware because it&amp;rsquo;s mapped to the CPU.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d_fb.png&#34;
	width=&#34;562&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d_fb_hu_5eeafb428738dd6a.png 480w, https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d_fb_hu_9be9694a3b2fcfa4.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;99&#34;
		data-flex-basis=&#34;239px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If the framerate ever drops below 60 FPS, the output of both screens will be
stable, no matter how long the wait is until the next frame is rendered.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No CPU or DMA processing is needed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;All 256x192 pixels of the screens are used.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The latency of the 3D rendered image is high. The capture unit saves the 3D
output to the same bank that is being used as framebuffer, but it is saved
at the same time the framebuffer is sent to the screen, which means the actual
output is frame stored in the framebuffer from the last time it was drawn, 2
frames ago.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The screen effects based on changing the horizontal scroll every scanline
don&amp;rsquo;t work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The debug test console can&amp;rsquo;t be used. The main screen always uses the contents
of VRAM directly, it isn&amp;rsquo;t possible to layer anything on top of it. The main
and sub screens switch every frame, so it wouldn&amp;rsquo;t be possible to display a
stable console on any screen.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The high latency of this mode may make it unsuitable for fast-paced games.
Also, due to the lack of a usable debug text console, it may not be useful for
developers.&lt;/p&gt;
&lt;p&gt;If latency isn&amp;rsquo;t an issue in your game, it is possible to use this mode for the
release version of the game, after you don&amp;rsquo;t rely on the debug console for
anything.&lt;/p&gt;
&lt;h2 id=&#34;6-dual-screen-3d-dma-mode&#34;&gt;6. Dual screen 3D DMA mode
&lt;/h2&gt;&lt;p&gt;The source code &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/nitro-engine/src/commit/8c323c7e2c29bf0b52951ac2756139026f09f269/source/NEGeneral.c#L735&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;for this mode is here&lt;/a&gt;
and &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/nitro-engine/src/commit/8c323c7e2c29bf0b52951ac2756139026f09f269/source/NEGeneral.c#L518&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this is the code to initialize the debug console&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a class=&#34;link&#34; href=&#34;https://github.com/Gericom&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gericom&lt;/a&gt; for all the advice regarding
this system!&lt;/p&gt;
&lt;p&gt;This system is the most complex one, by far. It combines the ability of having
stable output with low framerates, the ability of showing special effects, and
the ability to have a debug console. However, this has a cost in CPU time.&lt;/p&gt;
&lt;p&gt;It is always required to use 2 VRAM banks to hold the two framebuffers of the
screens. This mode is similar to the previous one, but it takes the current VRAM
bank used as destination of the video capture unit, and it copies it to a pseudo
framebuffer in VRAM I with DMA. By copying every line right after it has been
drawn it is possible to use VRAM I as a 16 bit bitmap.&lt;/p&gt;
&lt;p&gt;The main problem is that VRAM I isn&amp;rsquo;t big enough to hold a full 256x192. The
workaround is to either write out of bounds and rely on the mirroring of
addresses of VRAM I, or to only copy to the first line of VRAM I, and to stretch
it to fill the whole screen. Nitro Engine uses this last system so that the rest
of VRAM I can be used for other things.&lt;/p&gt;
&lt;p&gt;VRAM banks are used like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM A, B: Textures.&lt;/li&gt;
&lt;li&gt;VRAM C: Framebuffer of main screen and debug console of main screen.&lt;/li&gt;
&lt;li&gt;VRAM D: Framebuffer.&lt;/li&gt;
&lt;li&gt;VRAM E: Texture palettes.&lt;/li&gt;
&lt;li&gt;VRAM I: Pseudo framebuffer and debug console of sub screen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can see, there are two copies of the console. This is done to save VRAM.
In short, there is a lot of unused memory in VRAM C, D and I with this setup.
In odd frames the console is displayed on the sub screen from VRAM I; in even
frames it is displayed in the main screen from VRAM C.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Odd frames:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM C is mapped to the CPU.&lt;/li&gt;
&lt;li&gt;VRAM D is mapped as main engine background. It holds a 16 bit framebuffer.&lt;/li&gt;
&lt;li&gt;VRAM I is mapped as sub engine background. It holds one line of a 16 bit
framebuffer, as well as the debug console.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output of the main screen is the framebuffer stored in VRAM D.&lt;/p&gt;
&lt;p&gt;The output of the sub screen is the pseudo framebuffer stored in VRAM I, with
the debug console on top of it.&lt;/p&gt;
&lt;p&gt;The capture unit takes as input the 3D output. This is stored in VRAM C. The
important thing is that the image is written to VRAM C at the same rate it would
be drawn on the screen. If the DMA is setup to copy from VRAM C to VRAM I right
after each line is written to VRAM C, it is possible to display the captured
image right away. The only problem with this is that there is a one scanline
delay in the copy, so the first line of the screen won&amp;rsquo;t be able to show
anything useful. In Nitro Engine, the vertical blank interrupt handler sets it
to black so that it doesn&amp;rsquo;t show different values every frame.&lt;/p&gt;
&lt;p&gt;Finally, that one line is stretched to fill the whole screen, and that&amp;rsquo;s how by
simply copying the line every horizontal blanking period the screen can be
filled with different lines.&lt;/p&gt;
&lt;p&gt;This is different than in the dual 3D FB mode. In the FB mode it isn&amp;rsquo;t possible
to have this delay, so the image displayed on the screen is the one rendered 2
frames ago. In DMA mode the image being displayed is the one rendered this
frame.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Even frames:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRAM C is mapped as main engine background. It holds a 16 bit framebuffer.&lt;/li&gt;
&lt;li&gt;VRAM D is mapped to the CPU.&lt;/li&gt;
&lt;li&gt;VRAM I is mapped as sub engine background. It holds one line of a 16 bit
framebuffer, as well as the debug console (but the debug console isn&amp;rsquo;t used
right now).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output of the main screen is the framebuffer stored in VRAM C, with the
debug console stored in VRAM C on top of it.&lt;/p&gt;
&lt;p&gt;The output of the sub screen is the pseudo framebuffer stored in VRAM I.&lt;/p&gt;
&lt;p&gt;The capture unit takes as input the 3D output. The same notes about the DMA
apply as in odd frames.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d_dma.png&#34;
	width=&#34;622&#34;
	height=&#34;623&#34;
	srcset=&#34;https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d_dma_hu_9e30075b40fd44ad.png 480w, https://skylyrac.net/p/2023-10-12-dual-screen-3d-on-nds/ne_dual_3d_dma_hu_5d556817551aac43.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;99&#34;
		data-flex-basis=&#34;239px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Note that VRAM D doesn&amp;rsquo;t require a copy of the console, only VRAM C and I. Also,
libnds only supports printing to one console at a time, so it is needed to load
the font to both VRAM C and I, setup the map there, and then synchronize both
maps manually. Which bank to use as main console bank? VRAM I, because it is
always mapped as sub background RAM. Nitro Engine copies the map from VRAM I to
VRAM C whenever VRAM C is mapped as main background RAM.&lt;/p&gt;
&lt;p&gt;VRAM C (128 KB) is arranged like this:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Memory range&lt;/th&gt;
          &lt;th&gt;Size&lt;/th&gt;
          &lt;th&gt;Used as&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;0x06000000 - 0x06001000&lt;/td&gt;
          &lt;td&gt;4 KB&lt;/td&gt;
          &lt;td&gt;Tile base 0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;Free&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;0x06004000 - 0x06004800&lt;/td&gt;
          &lt;td&gt;2 KB&lt;/td&gt;
          &lt;td&gt;Map base 8&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;Free&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;0x06008000 - 0x06020000&lt;/td&gt;
          &lt;td&gt;96 KB&lt;/td&gt;
          &lt;td&gt;BMP base 0 (256x192)&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;VRAM viewer: &lt;a class=&#34;link&#34; href=&#34;https://mtheall.com/vram.html#T1=3&amp;amp;NT1=128&amp;amp;MB1=8&amp;amp;TB1=0&amp;amp;T2=6&amp;amp;MB2=2&amp;amp;S2=1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://mtheall.com/vram.html#T1=3&amp;NT1=128&amp;MB1=8&amp;TB1=0&amp;T2=6&amp;MB2=2&amp;S2=1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The reason to shift the framebuffer is that map bases over index 31 can&amp;rsquo;t be
accessed normally. It requires setting DISPCNT map base 64 KB step to a non-zero
value, which would affect all backgrounds. By shifting the bitmap it is possible
to use low indices and not have to worry about DISPCNT.&lt;/p&gt;
&lt;p&gt;VRAM I (16 KB) is arranged like this:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Memory range&lt;/th&gt;
          &lt;th&gt;Size&lt;/th&gt;
          &lt;th&gt;Used as&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;0x06208000 - 0x06209000&lt;/td&gt;
          &lt;td&gt;4 KB&lt;/td&gt;
          &lt;td&gt;Tile base 2&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;Free&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;0x0620B000 - 0x0620B200&lt;/td&gt;
          &lt;td&gt;512 B&lt;/td&gt;
          &lt;td&gt;Framebuffer (one line, 256 pixels)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;Free&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;0x0620B800 - 0x0620C000&lt;/td&gt;
          &lt;td&gt;2 KB&lt;/td&gt;
          &lt;td&gt;Map base 23&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;VRAM viewer: &lt;a class=&#34;link&#34; href=&#34;https://mtheall.com/vram.html#SUB=1&amp;amp;T1=3&amp;amp;NT1=128&amp;amp;MB1=23&amp;amp;TB1=2&amp;amp;T2=6&amp;amp;MB2=2&amp;amp;S2=0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://mtheall.com/vram.html#SUB=1&amp;T1=3&amp;NT1=128&amp;MB1=23&amp;TB1=2&amp;T2=6&amp;MB2=2&amp;S2=0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yes, there is an overlap between the framebuffer and the tileset. The size of
each tileset slot is 16 KB, so there is only space for one tileset in VRAM I.
Unfortunately, there is also only one slot for bitmaps in VRAM I, as they are
organized in 16 KB slots. Both slots need to share the space.&lt;/p&gt;
&lt;p&gt;Luckily, the tileset of the console doesn&amp;rsquo;t use the whole 16 KB. The current
console of libnds uses up to 256 characters, which requires (for a 4 bpp
tileset) 8 KB of VRAM. This means that anything in the second half of the bank
(VRAM I is 16 KB in size) can be used for maps or to store the pseudo
framebuffer line.&lt;/p&gt;
&lt;p&gt;8 KB is the same size as 16 lines in a 16-bit background. We can setup our
16-bit bitmap as if it started at the same base as the tileset, and we can store
our line bitmap at some point between 16 and 32 lines.&lt;/p&gt;
&lt;p&gt;Now, remember that the map uses the last 2 KB of the VRAM bank, and that uses as
much memory as 8 lines of a 16-bit bitmap. The free lines of the bitmap are
actually 16 to 24.&lt;/p&gt;
&lt;p&gt;Nitro Engine uses line 20, located at offset 0x3000 from the start of the bank.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If the framerate ever drops below 60 FPS, the output of both screens will be
stable, no matter how long the wait is until the next frame is rendered.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The latency of the 3D rendered image is zero. It is directly displayed on the
screen without any delay.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The screen effects based on changing the horizontal scroll every scanline
work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The debug console is supported.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Some CPU and DMA processing is needed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Display lists can&amp;rsquo;t be sent to the GPU using the DMA in GFX FIFO mode because
of the conflicts with the HBL DMA used to copy frames from VRAM C and D to
VRAM I. This adds a bit of overhead to the process (but not that much)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The first row of the screens remains unused. Only 256x191 pixels are used.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is the mode I&amp;rsquo;d recommend everyone to use for your applications. The CPU
overhead is well worth the reliability under low framerates, the availability of
the debug console and the low latency of the 3D output.&lt;/p&gt;
&lt;h2 id=&#34;7-conclusion&#34;&gt;7. Conclusion
&lt;/h2&gt;&lt;p&gt;Yes, this is complicated.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve tried to give as much flexibility to the developers as possible, and this
is the result. It is certainly overwhelming for someone who has never done
anything similar. I&amp;rsquo;ve also tried to keep compatibility with the old unreliable
dual 3D system, just in case the new ones break some game created with old
versions of Nitro Engine.&lt;/p&gt;
&lt;p&gt;My advice is to use the DMA method and forget about the others. The classic dual
3D system is too unreliable, you can&amp;rsquo;t expect to have a game that always draws
exactly 60 FPS. The FB method has a pretty big latency when displaying the 3D
output, so it is only useful for slow-paced games.&lt;/p&gt;
&lt;p&gt;I hope that this post has helped you understand how tricky this is, and how
flexible the NDS video hardware is!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>BlocksDS SDK</title>
        <link>https://skylyrac.net/p/2023-08-18-blocksds-sdk/</link>
        <pubDate>Fri, 18 Aug 2023 17:44:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2023-08-18-blocksds-sdk/</guid>
        <description>&lt;p&gt;A few months ago I created &lt;a class=&#34;link&#34; href=&#34;hhttps://codeberg.org/blocksds/sdk&#34; &gt;BlocksDS&lt;/a&gt;, a new
SDK for Nintendo DS. It uses libnds, DS WiFI and Maxmod, so it is compatible
with projects that use devkitARM. The toolchain it uses comes from
&lt;a class=&#34;link&#34; href=&#34;https://wonderful.asie.pl&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Wonderful Toolchain&lt;/a&gt; by &lt;a class=&#34;link&#34; href=&#34;https://asie.pl&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;asie&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Its main objective is to remain as compatible as possible with old projects that
use devkitARM, while adding new features that have been needed for a long time,
but that would have never been added to the original repositories of devkitPro.&lt;/p&gt;
&lt;p&gt;In order to achieve this, the libraries have been forked, and there are some
visible improvements over devkitARM already:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Binaries are smaller and they use less RAM. The main reasons for that are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Instead of using &lt;a class=&#34;link&#34; href=&#34;https://sourceware.org/newlib&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;newlib&lt;/a&gt;, BlocksDS uses
&lt;a class=&#34;link&#34; href=&#34;https://github.com/picolibc/picolibc&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;picolibc&lt;/a&gt; (thanks to Wonderful
Toolchain). The &lt;code&gt;tinystdio&lt;/code&gt; of picolibc has smaller versions of &lt;code&gt;stdio&lt;/code&gt;
functions (like &lt;code&gt;scanf()&lt;/code&gt;, &lt;code&gt;printf()&lt;/code&gt; or &lt;code&gt;fopen()&lt;/code&gt;) than newlib.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There have been some changes that optimize memory usage in libnds:
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/libnds/pulls/1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;[1]&lt;/a&gt;,
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/libnds/pulls/2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;[2]&lt;/a&gt; and
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/libnds/pulls/24&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;[3]&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BlocksDS doesn&amp;rsquo;t have anything similar to &lt;code&gt;devoptab&lt;/code&gt;, which is used in
devkitARM. While this is very flexible, and very useful in platforms like
the Wii or Switch, it&amp;rsquo;s too big for the GBA or NDS, where it doesn&amp;rsquo;t offer
almost any benefit. There is more information about this change further down
this article.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://blocksds.skylyrac.net/docs/guides/licenses&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;licensing status&lt;/a&gt;
of all libraries has been clarified and documented. This is important.
Anything that doesn&amp;rsquo;t have a license defaults to &amp;ldquo;all rights reserved&amp;rdquo;, not
&amp;ldquo;public domain&amp;rdquo;. Many things that devkitPro distributes don&amp;rsquo;t have a license.
The examples don&amp;rsquo;t have a license, but that&amp;rsquo;s not the worst thing, as it can
be argued that most of them are trivial and copyright doesn&amp;rsquo;t apply to them.
However, it is a problem for non-trivial code, and it looks like the devkitPro
maintainers seem to mistakenly believe that the lack of a license is fine, and
that it &lt;a class=&#34;link&#34; href=&#34;https://github.com/devkitPro/wut/pull/148#issuecomment-652337319&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;leaves the code in the public domain&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;They also may be in violation of the &lt;a class=&#34;link&#34; href=&#34;https://www.gnu.org/licenses/gpl-3.0.en.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GPLv3&lt;/a&gt;
by distributing build scripts for GPLv3-licensed software under incompatible
&lt;a class=&#34;link&#34; href=&#34;https://github.com/devkitPro/buildscripts/blob/f06196c43cca687108c6f73fe0b48ed01a606d85/build-devkit.sh#L17-L19&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;restrictive terms&lt;/a&gt;.
Any build scripts for GPLv3 software must also be released under the GPLv3:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &amp;ldquo;Corresponding Source&amp;rdquo; for a work in object code form means all the
source code needed to generate, install, and (for an executable work) run
the object code and to modify the work, including scripts to control those
activities.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The biggest practical problem for BlocksDS is that a library crucial for NDS
development doesn&amp;rsquo;t have any license: &lt;a class=&#34;link&#34; href=&#34;https://github.com/devkitPro/libfilesystem/issues/3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NitroFS&lt;/a&gt;.
I tried to contact the original author in every way I could think of with no
luck. This means that the library isn&amp;rsquo;t open source, and it can&amp;rsquo;t be used
without permission from the &lt;a class=&#34;link&#34; href=&#34;http://blea.ch/wiki/index.php/Nitrofs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;author&lt;/a&gt;.
The devkitPro maintainers aren&amp;rsquo;t interested in fixing this situation.&lt;/p&gt;
&lt;p&gt;BlocksDS does thing in a different way. devkitARM uses &lt;a class=&#34;link&#34; href=&#34;https://github.com/devkitPro/libfat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;libfat&lt;/a&gt;
by Chishm to access FAT filesystems and interface with the DS hardware, and
&lt;a class=&#34;link&#34; href=&#34;https://github.com/devkitPro/libfilesystem&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;libfilesystem&lt;/a&gt; to use the
filesystem embedded in the NDS ROM (and it uses the official filesystem format
of the official SDK provided by Nintendo).&lt;/p&gt;
&lt;p&gt;BlocksDS uses &lt;a class=&#34;link&#34; href=&#34;http://elm-chan.org/fsw/ff/00index_e.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;FatFs&lt;/a&gt; by Elm and a
thin wrapper on top of libnds to access libnds functions. Instead of using the
official format of Nintendo, BlocksDS uses what I&amp;rsquo;ve decided to call
&lt;strong&gt;NitroFAT&lt;/strong&gt;, which appends a FAT filesystem image to the NDS ROM, and it uses
FatFs to access it. This allows BlocksDS to reuse code, as accessing the
filesystem of the SD card and the filesystem of the ROM uses the same code.
This is one of the reasons why NDS programs built with BlocksDS are smaller
than with devkitARM.&lt;/p&gt;
&lt;p&gt;This took a lot of effort to get working, and it is the best example I can
think of about why it is important to license your code so that people can
reuse it when you move on and stop caring about it.&lt;/p&gt;
&lt;p&gt;So, in order to ensure that this project can survive over time, all files in
all repositories of BlocksDS use &lt;a class=&#34;link&#34; href=&#34;https://spdx.dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SPDX&lt;/a&gt; identifiers, so that
the licensing status of all individual files is always clear, which will allow
other projects to reuse the code of BlocksDS easily if they want. It also
allows other people to fork BlocksDS if something happens in the future.&lt;/p&gt;
&lt;p&gt;I also talked to the author to change the
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/libnds/commit/60e7f002daf4be9588865e654b9776e3004d002f&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;license of GL2D&lt;/a&gt;
to Zlib, like the rest of &lt;code&gt;libnds&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There is now basic multithreading support. &lt;code&gt;libnds&lt;/code&gt; wasn&amp;rsquo;t thread-safe, so
it had to be modified so that multithreading works safely. Thread-local
storage support has also been added. You can define variables that are
unique per thread like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;__thread&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;my_variable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;__thread&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;other_variable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DLDI can now be used from both the ARM9 and ARM7.&lt;/p&gt;
&lt;p&gt;You can make the ARM9 ask the ARM7 to load files in one thread. While the ARM7
load files the ARM9 can be doing other things in other threads, so you aren&amp;rsquo;t
blocked. This can also be done when loading files from the SD card of the DSi.
This has always been one of the limitations that annoyed me about creating
games with devkitARM, and now it&amp;rsquo;s fixed.&lt;/p&gt;
&lt;p&gt;There is a big issue with DLDI drivers, and it&amp;rsquo;s that some of them have been
compiled for the ARM9 and can&amp;rsquo;t run on the ARM7. This is why, by default,
BlocksDS makes them run from the ARM9. The code must explicitly set ARM7 mode,
or the user needs to use a DLDI driver built with a
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/sdk/src/commit/c7e3f22054dc2b473089d064c3780f6c2fea1889/tests/dldi_arm9_arm7&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;new configuration flag&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The DSi camera is supported (thanks, asie!). It&amp;rsquo;s still quite basic, but
enough to be able to take photos from the front and back cameras.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;libnds&lt;/strong&gt; has been documented in many places, like the
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/libnds/src/commit/9763b22fee597025777ec4c853c94d95944ffe37/source/arm9/system/mpu_setup.s&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MPU setup&lt;/a&gt;,
the &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/libnds/src/commit/9763b22fee597025777ec4c853c94d95944ffe37/source/common/fifo_ipc_messages.h&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;FIFO system&lt;/a&gt;,
and the code that allows a program to &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/sdk/src/commit/c7e3f22054dc2b473089d064c3780f6c2fea1889/docs/exit-to-loader.rst&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;return to the loader&lt;/a&gt;
if the loader supports it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BlocksDS includes versions of &lt;code&gt;memcpy()&lt;/code&gt;, &lt;code&gt;memset()&lt;/code&gt; and &lt;code&gt;memmove()&lt;/code&gt;
optimmized for the CPUs of the NDS by using &lt;strong&gt;ndsabi&lt;/strong&gt;, a fork of
&lt;a class=&#34;link&#34; href=&#34;https://github.com/felixjones/agbabi&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;agbabi&lt;/a&gt; by felixjones.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ndstool&lt;/strong&gt; now supports multiple languages in the banner, as well as icons in
formats like PNG or GIF (even animated GIFs!).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;libxm7&lt;/strong&gt; has been added as an alternative to Maxmod.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;no$gba&lt;/strong&gt; debug messages are now supported in the ARM7, not only ARM9.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A few people have started to contribute with bugfixes, like &lt;a class=&#34;link&#34; href=&#34;https://asie.pl/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;asie&lt;/a&gt;,
&lt;a class=&#34;link&#34; href=&#34;https://github.com/lifehackerhansol&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;lifehackerhansol&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://pk11.us&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Pk11&lt;/a&gt;,
which I&amp;rsquo;m very grateful about!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is guide that helps new users &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/sdk/src/commit/c7e3f22054dc2b473089d064c3780f6c2fea1889/docs/porting-guide.rst&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;port devkitARM projects&lt;/a&gt;
to BlocksDS. Even though most code is compatible, there are a few things to
consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;BlocksDS is available on Windows and Linux. If you&amp;rsquo;re using Mac, you can use
the &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/sdk/src/commit/c7e3f22054dc2b473089d064c3780f6c2fea1889/docker&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Docker images&lt;/a&gt;
distributed by BlocksDS. There is no native way to use BlocksDS on Mac, and
currently there are no immediate plans to support it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Makefiles are completely different from the ones used in devkitARM. For
most users this won&amp;rsquo;t be a problem, the migration is very easy (it only
involves copying folder names from the old Makefiles to the new ones).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There is no &lt;code&gt;devoptab&lt;/code&gt; support. Most likely you&amp;rsquo;ve never heard of it or used
it directly, but &lt;code&gt;devoptab&lt;/code&gt; is the way that devkitARM uses to make things
like filesystem functions work (&lt;code&gt;fopen()&lt;/code&gt;, etc), or things like getting the
time and date from the OS (with &lt;code&gt;time()&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;BlocksDS supports the same features without any intermediate layers (like
&lt;code&gt;devoptab&lt;/code&gt;) between libc functions and the hardware functions. This is one
of the reasons why binaries generated by BlocksDS are smaller and require less
RAM to run.&lt;/p&gt;
&lt;p&gt;However, in rare situations where user code uses &lt;code&gt;devoptab&lt;/code&gt;, it won&amp;rsquo;t be
possible to migrate to BlocksDS without big changes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a list of projects that now benefit from using BlocksDS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/angband/angband/pull/5700&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Angband&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/DS-Homebrew/dsbf_dump/releases/tag/v1.0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;dsbf_dump&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/DS-Homebrew/GameYob&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GameYob&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/asiekierka/nitrotracker/releases/tag/0.4.3-unofficial&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NitrousTracker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/asiekierka/uxnds/releases/tag/v0.3.7&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;uxnds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/asiekierka/vnds/releases/tag/1.4.10-pre&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VNDS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to the work of the maintainers of the projects it was possible to
exhaustively test BlocksDS, and it&amp;rsquo;s now stable enough to be used by real
projects. A lot of work has been put into all of this by several people, so
it&amp;rsquo;s great that some projects have started to use it for real!&lt;/p&gt;
&lt;p&gt;Finally, I&amp;rsquo;d like to mention NFlib and Nitro Engine.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/knightfox75/nds_nflib&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NFlib&lt;/a&gt; is a library that
&lt;a class=&#34;link&#34; href=&#34;https://github.com/knightfox75&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NightFox&lt;/a&gt; created many years ago. It helps
developers create 2D games (and it has very basic 3D support). I&amp;rsquo;ve spent
quite a bit of time cleaning it up and documenting the library and examples
properly by adding Doxygen comments and translating everything from Spanish to
English (sorry, but it&amp;rsquo;s too easy for the documentation to be outdated if it&amp;rsquo;s
in multiple languages!).&lt;/p&gt;
&lt;p&gt;I also talked to the author to change the license to MIT instead of Creative
Commons. Note that Creative Commons is a license that
&lt;a class=&#34;link&#34; href=&#34;https://creativecommons.org/faq/#can-i-apply-a-creative-commons-license-to-software&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;shouldn&amp;rsquo;t be used for code&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/nitro-engine&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Nitro Engine&lt;/a&gt; is a library that I
created many years ago as well. It&amp;rsquo;s used to develop 3D games. I&amp;rsquo;ve spent some
time over the last few years cleaning it up and improving it. In fact, I came
up with the idea of BlocksDS when I was frustrated because I couldn&amp;rsquo;t
implement a system to load assets from the filesystem asynchronously with
devkitARM.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both libraries are now fully supported in BlocksDS. The examples in both
repositories will build with BlocksDS, and Nitro Engine comes with an example of
how to use both libraries in the same project, which can be found
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/nitro-engine/src/commit/db33780b45da84dcdb7aeb7e763dcff995469f04/examples/templates/using_nflib&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At the time of writing this post, the latest version of BlocksDS is
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/blocksds/sdk/releases/tag/v0.8.1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;0.8.1&lt;/a&gt;. Give it a try!
If you find any problems, or you have questions, feel free to open issues in the
repository (or send a pull request with a fix!).&lt;/p&gt;
&lt;p&gt;P.S.: I haven&amp;rsquo;t written anything in this blog for over 3 years&amp;hellip; I still have a
few more updates to post in the coming days!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2023-09-06)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This post has been updated to reflect the fact that Windows is now supported by
Wonderful Toolchain, which enables BlocksDS to work on Windows natively.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Raspberry Pi LED ambient lamp</title>
        <link>https://skylyrac.net/p/2020-06-27-rpi-led-ambient-lamp/</link>
        <pubDate>Sat, 27 Jun 2020 13:27:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2020-06-27-rpi-led-ambient-lamp/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2020-06-27-rpi-led-ambient-lamp/led-lamp.jpg" alt="Featured image of post Raspberry Pi LED ambient lamp" /&gt;&lt;p&gt;A few months ago (before the lockdown started) I was shopping at the Cambridge
city center, I popped by the &lt;a class=&#34;link&#34; href=&#34;https://www.raspberrypi.org/raspberry-pi-store/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Raspberry Pi Store&lt;/a&gt;
and I saw something called &lt;a class=&#34;link&#34; href=&#34;https://shop.pimoroni.com/products/mood-light-pi-zero-w-project-kit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Mood Light - Pi Zero W Project Kit&lt;/a&gt;. This is basically a kit that contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.raspberrypi.org/products/raspberry-pi-zero-w/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Raspberry Pi Zero W&lt;/a&gt;:
Pretty nice, as it has integrated WiFI.&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/pimoroni/unicorn-hat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Unicorn HAT&lt;/a&gt;: 32x4 RGB LED matrix
with a pretty simple Python library to control it.&lt;/li&gt;
&lt;li&gt;A plastic case to put everything in, for decoration.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I thought it looked pretty nice, and decided to buy it to play with it during
when the lockdown started.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2020-06-27-rpi-led-ambient-lamp/led-lamp.jpg&#34;
	width=&#34;960&#34;
	height=&#34;540&#34;
	srcset=&#34;https://skylyrac.net/p/2020-06-27-rpi-led-ambient-lamp/led-lamp_hu_f374c24cede9385b.jpg 480w, https://skylyrac.net/p/2020-06-27-rpi-led-ambient-lamp/led-lamp_hu_e7baf66475c32526.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;177&#34;
		data-flex-basis=&#34;426px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;I wrote a &lt;a class=&#34;link&#34; href=&#34;https://telegram.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Telegram&lt;/a&gt; bot a couple of years ago with
&lt;a class=&#34;link&#34; href=&#34;https://github.com/nickoala/telepot&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Telepot&lt;/a&gt;, and I thought that it would be
a good idea to repurpose it to control the lamp remotely. However, that was
only supposed to be the first step. Nobody really wants to have to type a
command to change the color of the lights, right? Also, it looks like that
Telepot has been deprecated, so it&amp;rsquo;s likely going to break at some point in the
future.&lt;/p&gt;
&lt;p&gt;The actual objective was to create a web user interface with
&lt;a class=&#34;link&#34; href=&#34;https://flask.palletsprojects.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Flask&lt;/a&gt;, expose it to my home network, and
to be able to control the lights pressing buttons in a website from my phone,
PC, and even let any guest that come to my home control the lights by
connecting to the WiFi network.&lt;/p&gt;
&lt;p&gt;This is a video of the result (it&amp;rsquo;s missing one effect that simulates fire,
though):&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=xjQCvFdkGJw&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.youtube.com/watch?v=xjQCvFdkGJw&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;how-does-it-work&#34;&gt;How does it work?
&lt;/h1&gt;&lt;p&gt;There are 3 main parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LED server&lt;/strong&gt;: Script that has to be run with root permissions. It listens to
connections to a specific port and affects the LEDs. It can also reboot or
shutdown your Raspberry Pi.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Telegram bot&lt;/strong&gt;: Telegram bot that runs with regular user permissions. It can
send commands to the LED server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;HTML server&lt;/strong&gt;: HTML server that sets up a website with some buttons that can
be used to control the LEDs. It sends commands to the LED server.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that you don&amp;rsquo;t need the Telegram bot and HTML server at the same time. Just
one is enough. Also, any program that connects to the right port can send the
same commands to the LED server. Both the Telegram bot and the web interface can
control the lights at the same time.&lt;/p&gt;
&lt;p&gt;All you have to do is turn the Raspberry Pi on anywhere in the flat and it will
connect to the WiFi network, start the servers, and from that point you can talk
to the Telegram bot or use the web interface to control it!&lt;/p&gt;
&lt;p&gt;The only problem is that you have to turn it off manually from the web interface
before switching the power off, that&amp;rsquo;s why both the web interface and the
Telegram bot support that command.&lt;/p&gt;
&lt;p&gt;For more information, check the code in my GitHub account:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/led-bot&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/led-bot&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>RGBDS - Rednex Game Boy Development System</title>
        <link>https://skylyrac.net/p/2018-02-05-rgbds/</link>
        <pubDate>Mon, 05 Feb 2018 23:42:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2018-02-05-rgbds/</guid>
        <description>&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/gbdev/rgbds&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RGBDS&lt;/a&gt; is a toolchain to develop in assembly
for the Game Boy. It is used by many projects nowadays, and I&amp;rsquo;m not talking
about small ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Disassemblies of games released during the lifetime of the GB:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/pret/pokered&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/pret/pokered&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/pret/pokecrystal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/pret/pokecrystal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/pret/pokepinball&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/pret/pokepinball&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Completely new projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/ISSOtm/Aevilia-GB&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/ISSOtm/Aevilia-GB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Of course, it&amp;rsquo;s the toolchain I use for my own projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/ucity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/ucity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/back-to-color&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/back-to-color&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/geometrix&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/geometrix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only real alternative is &lt;a class=&#34;link&#34; href=&#34;https://github.com/vhelin/wla-dx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;WLA DX&lt;/a&gt;, as
far as I know. I personally don&amp;rsquo;t like the syntax (because of small things like
using parentheses instead of square brackets for indirection) but it is probably
as powerful as RGBDS, and it&amp;rsquo;s worth taking a look at it if you want to do
something serious for the GB.&lt;/p&gt;
&lt;h2 id=&#34;history&#34;&gt;History
&lt;/h2&gt;&lt;p&gt;It was released in 1997 as ASMotor by Carsten Sørensen as a general-purpose
assembler for DOS/Win32. In 1999, it was modified by Justin Lloyd and released
as RGBDS. In 2009, Vegard Nossum adapted the code for the toolchain to be more
UNIX-like and released it as rgbds-linux. In 2010, Anthony J. Bentley forked the
repository and improved on it, becoming the reference implementation of RGBDS.
Then, in February 2017, he asked me if I wanted to be its new maintainer, I
accepted, and he moved the repository to a neutral username. Basically, I was
one of the few people still proposing new changes and fixes, so it was a safe
choice.&lt;/p&gt;
&lt;p&gt;Nowadays, this project is located here: &lt;a class=&#34;link&#34; href=&#34;https://github.com/gbdev/rgbds&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/gbdev/rgbds&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is important to know that during all this time (20 years!) many people have
contributed to it, not only the main maintainers mentioned above. This had left
the codebase in a really complicated licensing situation. The original code was
released without a license, and pretty much every new contributor used a
variation of the BSD or MIT license for new changes.&lt;/p&gt;
&lt;p&gt;This is why I tried (and succeeded!) to get all the main authors to agree to
change the license so that all the codebase would have the same one. In the end,
all of the main contributors answered and gave permission to relicense their
code, and the MIT license was chosen: &lt;a class=&#34;link&#34; href=&#34;https://github.com/rednex/rgbds/pull/225&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/rednex/rgbds/pull/225&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In any case, because of its story, I don&amp;rsquo;t think it makes sense to consider this
the project of a specific person in particular. At some point it just becomes a
project of the community.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works
&lt;/h2&gt;&lt;p&gt;RGBDS is divided into &lt;strong&gt;rgbasm&lt;/strong&gt;, &lt;strong&gt;rgblink&lt;/strong&gt;, &lt;strong&gt;rgbfix&lt;/strong&gt; and &lt;strong&gt;rgbgfx&lt;/strong&gt;. In the
past, there was another tool called rgblib, but it was quite pointless as nobody
really used it, and the object format breaks quite often when adding new
features to the toolchain.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;rgbasm&lt;/strong&gt;: Assembler.&lt;/p&gt;
&lt;p&gt;It takes a file with source code as input and generates an object file as
output. It uses yacc/bison to parse files, which is a bit problematic because
of the source code syntax and how hard it is to resolve conflicts.&lt;/p&gt;
&lt;p&gt;It is really flexible. It has support for macros, unions, even for referencing
local labels through the parent label. Of course, the address of labels is not
always known at compile time, it is only known if the value is directly
assigned, or if the base address of the section is directly assigned. In order
to be able to resolve their address at linking time, or even be able to
calculate simple expressions with them (addition, bit masks&amp;hellip;) there is a RPN
language that is used in object files to tell the linker how to operate with
them. Each value that has to be modified by the linker generates a patch of
RPN instructions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;rgblink&lt;/strong&gt;: Linker.&lt;/p&gt;
&lt;p&gt;It reads all object files generated by rgbasm (and potentially a linkerscript
with information about where to place sections) and generates a raw GB ROM,
that is not generally ready to directly use in a GB.&lt;/p&gt;
&lt;p&gt;In short, it places all sections in their final locations and calculates the
final value of all RPN patches. It can also generate files with a list of
labels and addresses to help debugging.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;rgbfix&lt;/strong&gt;: ROM fixer.&lt;/p&gt;
&lt;p&gt;Used to fix a finished GB ROM. There are some fields in the header that must
have the correct value for the game to boot in a real GB. Some of this fields
are difficult to fill at linking time, so it&amp;rsquo;s easier to have an external tool
for it, that&amp;rsquo;s where rgbfix comes in handy. It also pads a ROM if the size
isn&amp;rsquo;t a power of two.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;rgbgfx&lt;/strong&gt;: Graphics converter.&lt;/p&gt;
&lt;p&gt;This tool converts png files into the format that the GB uses. I must admit
that I&amp;rsquo;ve never used this tool, but it is used in disassemblies extensively.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;I find it really interesting that this toolchain has managed to survive for such
a long time, and that it is still used so much. It&amp;rsquo;s mostly used by
disassemblers, I must admit, but hey!&lt;/p&gt;
&lt;p&gt;As I&amp;rsquo;ve said before, this project wouldn&amp;rsquo;t be nearly as useful if it wasn&amp;rsquo;t
thanks to all of its contributors. Because of it, it is always open to
contributions. They don&amp;rsquo;t have to be big or fancy, even small bug reports (or
bug fixes!) are welcome. So yeah, let&amp;rsquo;s keep this project alive!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Port of Trusted Firmware-A to the Raspberry Pi 3</title>
        <link>https://skylyrac.net/p/2018-02-01-port-arm-tf-to-rpi3/</link>
        <pubDate>Thu, 01 Feb 2018 23:54:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2018-02-01-port-arm-tf-to-rpi3/</guid>
        <description>&lt;p&gt;This is a small project I worked on before Christmas. The
&lt;a class=&#34;link&#34; href=&#34;https://github.com/ARM-software/arm-trusted-firmware%3e&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Trusted Firmware-A&lt;/a&gt; is
a reference implementation of a secure firmware for ARMv8-A CPUs. It has ports
to both AArch64 (64-bit Arm Instruction Set Architecture) and AArch32 (32-bit
Arm ISA). AArch32 is almost the same as ARMv7-A, for backwards compatibility.&lt;/p&gt;
&lt;p&gt;The SoC of the Raspberry Pi 3 is the Broadcom BCM2937, which has 4 Cortex-A53
cores. The Cortex-A53 is a microarchitecture that implements the ARMv8-A ISA
with both 64 and 32-bit modes, so it is possible to port the Trusted Firmware-A.
At work I&amp;rsquo;m one of the engineers working on the Trusted Firmware-A, and I really
like the Raspberry Pi, so I simply couldn&amp;rsquo;t resist, I needed to have the Trusted
Firmware running on it.&lt;/p&gt;
&lt;p&gt;Even though the Trusted Firmware has ports to both AArch64 and AArch32, the one
that interests me is AArch64. There is no real advantage for making the port for
Raspberry Pi run in AArch32 mode. The firmware runs in EL3, the highest
privilege execution level. The architecture allows to downgrade from 64 to
32-bit when reducing the privilege level, but not to increase it. That means
that, for example, if the firmware is running in 64-bit mode, it is possible to
have a 64 or a 32-bit hypervisor in EL2. Similarly, an operating system in
64-bit mode in EL1 can execute both 64 and 32-bit user applications in EL0. In
short, a 64-bit firmware allows any other privilege level to use 64 or 32-bit
mode, but a 32-bit firmware would restrict them to execute in 32-bit mode.&lt;/p&gt;
&lt;p&gt;Also, it is important that this port works with
&lt;a class=&#34;link&#34; href=&#34;https://www.raspberrypi.org/downloads/raspbian&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Raspbian&lt;/a&gt;. It is the Linux
distribution for the Raspberry Pi with the best support, as it has the support
of the Raspberry Pi Foundation itself. If a port of the Trusted Firmware is to
be done, it&amp;rsquo;s a good idea to make it work with Raspbian.&lt;/p&gt;
&lt;p&gt;This port is based on the work of Ard Biesheuvel
&lt;a class=&#34;link&#34; href=&#34;https://github.com/ardbiesheuvel&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;@ardbiesheuvel&lt;/a&gt;, explained
&lt;a class=&#34;link&#34; href=&#34;http://www.workofard.com/2017/02/uefi-on-the-pi&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;in this article&lt;/a&gt;. The port is
in &lt;a class=&#34;link&#34; href=&#34;https://github.com/ardbiesheuvel/arm-trusted-firmware/tree/rpi3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this repository&lt;/a&gt;.
The port has been heavily modified. For starters, that port didn&amp;rsquo;t manage to
boot Linux or to release the secondary CPUs from their wait loop (the RAM used
as a mailbox wasn&amp;rsquo;t initialized to 0 before entering the wait loop).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important note&lt;/strong&gt;: Even though the Trusted Firmware-A is a reference of a
secure boot flow, the Raspberry Pi 3 doesn&amp;rsquo;t isn&amp;rsquo;t a secure platform. The memory
available to the CPUs is the DRAM, which can be accessed when the CPU is in
Non-secure and Secure modes. However, in order to emulate the normal bootflow,
the memory map is divided in a few regions.&lt;/p&gt;
&lt;p&gt;In short, this is a port that can be used to play around with, implement
standard services that the OS can use, etc. This is not meant to be used to
implement secure services in any way.&lt;/p&gt;
&lt;p&gt;It could be possible to emulate secure RAM by using the hypervisor translation
tables to hide some memory from the OS, which would act as SRAM. This is
non-trivial, and it is outside of the scope of this project.&lt;/p&gt;
&lt;h2 id=&#34;getting-the-trusted-firmware-a-to-boot&#34;&gt;Getting the Trusted Firmware-A to boot
&lt;/h2&gt;&lt;p&gt;First of all, I connected a UART to USB cable to the Mini UART located in the
pin header. I verified that the connection was working by using &lt;code&gt;screen&lt;/code&gt; to
connect to Linux through it. To enable this connection, the file &lt;code&gt;config.txt&lt;/code&gt;
on the root of the SD card must contain a line that says &lt;code&gt;enable_uart=1&lt;/code&gt;.
Also, I added &lt;code&gt;console=serial0,115200 console=tty1&lt;/code&gt; to the file &lt;code&gt;cmdline.txt&lt;/code&gt;.
Once I verified that it was working, I started to take a look at the code of
the port.&lt;/p&gt;
&lt;p&gt;The port was quite old by the time I started to work on this project, so the
first thing that I did was to rebase the branch, replace some old APIs and
libraries by the new ones, and made sure that it compiled. I also enabled some
CPU errata workarounds that can affect the Cortex-A53. Then, I had to figure out
how to make it run. I needed to get all CPU cores running the same binary at EL3
in AArch64 mode.&lt;/p&gt;
&lt;p&gt;The booting process of the Raspberry Pi is quite unusual. The SoC has a
VideoCore IV located between all the Arm cores and the DRAM. It has its own MMU
and tricks the Arm cores into thinking that the physical memory map is different
than it actually is! This VideCore is also the one that has a ROM bootloader
that loads the rest of the files from the SD card. The file &lt;code&gt;config.txt&lt;/code&gt; tells
it how to load them, but most of the options of interest to this project are
undocumented. After some googling I managed to find the ones I needed and got
all 4 cores booting in AArch64 mode in EL3. For more details about it, check the
documentation of the port in the official repository of the Trusted Firmware:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/plat/rpi3.rst&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/plat/rpi3.rst&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In short, the kernel has to be renamed to &lt;code&gt;kernel8.img&lt;/code&gt; and the firmware has to
be packaged as one single binary and named &lt;code&gt;armstub8.bin&lt;/code&gt;. Then, in the
&lt;code&gt;config.txt&lt;/code&gt; file I added the following lines to tell the loader where to load
the files in DRAM.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;enable_uart=1
kernel_address=0x01000000
device_tree_address=0x02000000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One good thing about this unusual bootflow is that it is literally impossible to
brick the Raspberry Pi, you just need to write the correct files to your SD card
and it will boot again. Also, it gives the user a lot of flexibility on how to
boot the Arm cores. Normally it&amp;rsquo;s not that simple to select AArch64 or AArch32
at the highest Execution Level, that&amp;rsquo;s fixed by the platform. In the Raspberry
Pi, that can be changed by changing a value in the configuration file.&lt;/p&gt;
&lt;p&gt;This &lt;a class=&#34;link&#34; href=&#34;https://github.com/swarren/rpi-3-aarch64-demo&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;demo by Stephen Warren&lt;/a&gt;
was useful to test that my code was running in the conditions I needed. That
demo shows the same message per each CPU with the values of some registers, like
&lt;code&gt;CurrentEL&lt;/code&gt;, that shows the EL in which the code is running.&lt;/p&gt;
&lt;p&gt;Once this was ready, I just needed to replace that demo by my binary of the
firmware and check if the port was working. I decided to use the binary of the
demo BL33 image, the final payload to be loaded by the firmware, where it jumps
after initializing everything. I got the following output:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;VERBOSE: Reserved 0x12000 bytes (discarded 0x7000 bytes above)
VERBOSE: Trusted SRAM seen by this BL image: 181000 - 0x200000
VERBOSE: Code region: 0 - 0x5f90
ERROR:   mmap_add_region_check() failed. error -22
ASSERT:  lib/xlat_tables_v2/xlat_tables_internal.c:753:0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Success! Sort of, anyway. That error is &lt;code&gt;EINVAL&lt;/code&gt;. It means that there is some
sort of overlap of memory regions, or that the platform is trying to map regions
with invalid values for some reason. I initially thought that it was just that
there wasn&amp;rsquo;t enough memory reserved to setup the translation tables. Anyway,
easy enough to fix! I eventually got this output:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NOTICE:  Booting Trusted Firmware
NOTICE:  BL1: v1.4(debug):v1.4-308-g2082b0ad
NOTICE:  BL1: Built : 02:47:22, Nov  4 2017
INFO:    BL1: RAM 0x3ee000 - 0x3f7000
INFO:    BL1: cortex_a53: errata workaround for 835769 was applied
INFO:    BL1: cortex_a53: errata workaround for 843419 was applied
INFO:    BL1: cortex_a53: errata workaround for 855873 was applied
INFO:    BL1: Loading BL2
INFO:    Loading image id=1 at address 0x3b4000
INFO:    Image id=1 loaded: 0x3b4000 - 0x3ba1f0
NOTICE:  BL1: Booting BL2
INFO:    Entry point address = 0x3b4000
INFO:    SPSR = 0x3c5
NOTICE:  BL2: v1.4(debug):v1.4-308-g2082b0ad
NOTICE:  BL2: Built : 02:47:22, Nov  4 2017
INFO:    BL2: Doing platform setup
INFO:    BL2: Loading image id 3
INFO:    Loading image id=3 at address 0x3e0000
INFO:    Image id=3 loaded: 0x3e0000 - 0x3e8080
INFO:    BL2: Loading image id 5
INFO:    Loading image id=5 at address 0x600000
INFO:    Image id=5 loaded: 0x600000 - 0x6003f4
NOTICE:  BL1: Booting BL31
INFO:    Entry point address = 0x3e0000
INFO:    SPSR = 0x3cd
NOTICE:  BL31: v1.4(debug):v1.4-308-g2082b0ad
NOTICE:  BL31: Built : 02:47:22, Nov  4 2017
INFO:    BL31: Initializing runtime services
INFO:    BL31: cortex_a53: errata workaround for 835769 was applied
INFO:    BL31: cortex_a53: errata workaround for 843419 was applied
INFO:    BL31: cortex_a53: errata workaround for 855873 was applied
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x600000
INFO:    SPSR = 0x3c9

Hello, world!
this_cpuid:0
MPIDR:0000000080000000
r0:0000000000000000
r1:0000000000000000
r2:0000000000000000
r3:0000000000000000
CurrentEL:8
SPSel:1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The exception level is encoded in bits 3 and 2 of register &lt;code&gt;CurrentEL&lt;/code&gt;, which
means that this code is running at EL2, as we want! As you can see, the demo
only prints the registers of one CPU. This is normal, as all secondary cores are
supposed to wait for the OS to power them ON (or, in this case, release them
from a wait loop).&lt;/p&gt;
&lt;h2 id=&#34;getting-linux-to-boot&#34;&gt;Getting Linux to boot
&lt;/h2&gt;&lt;p&gt;The next step was to actually get the Linux kernel booting. The Linux kernel
image simply replaces the demo I was using as BL33 image.&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t have a 64-bit kernel to test with, though, just a 32-bit one (the one
that comes with Raspbian). According to the Linux boot documentation for the Arm
32-bit kernel (located in &lt;code&gt;Documentation/arm/Booting&lt;/code&gt; in the Linux kernel
tree), it likes to start in Hypervisor mode. I just needed to tweak the final
step of the firmware (the jump to the BL33 entrypoint) so that it jumped to this
mode instead of EL2 in AArch64 mode.&lt;/p&gt;
&lt;p&gt;This is easy, it is only needed to modify the value of &lt;code&gt;SPSR&lt;/code&gt; at the time it
jumps to BL33. With the correct value, it jumps to the entrypoint in AArch32 in
hypervisor mode. I didn&amp;rsquo;t want to close the door to a 64-bit kernel, so I just
created a build option, &lt;code&gt;RPI3_BL33_IN_AARCH32&lt;/code&gt;, that would let the developer
choose EL2 in AArch64 or Hypervisor in AArch32.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NOTICE:  Booting Trusted Firmware
NOTICE:  BL1: v1.4(debug):v1.4-310-gf49906c8-dirty
NOTICE:  BL1: Built : 23:55:50, Nov  4 2017
NOTICE:  BL1: Booting BL2
NOTICE:  BL2: v1.4(debug):v1.4-310-gf49906c8-dirty
NOTICE:  BL2: Built : 23:55:50, Nov  4 2017
NOTICE:  BL1: Booting BL31
NOTICE:  BL31: v1.4(debug):v1.4-310-gf49906c8-dirty
NOTICE:  BL31: Built : 23:55:50, Nov  4 2017
[    1.060413] CPU1: failed to come online
[    2.101140] CPU2: failed to come online
[    3.141884] CPU3: failed to come online
[    3.327640] bcm2835-aux-uart 3f215040.serial: could not get clk: -517

Raspbian GNU/Linux 9 raspberrypi ttyS0
raspberrypi login:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The secondary cores couldn&amp;rsquo;t come online because this kernel doesn&amp;rsquo;t know about
PSCI, which is the standard way of powering on Arm cores. But that&amp;rsquo;s not a
problem, there is a workaround, the kernel also has support for booting
secondary cores by making them wait in a wait loop.&lt;/p&gt;
&lt;h2 id=&#34;getting-the-secondary-cores-to-work&#34;&gt;Getting the secondary cores to work
&lt;/h2&gt;&lt;p&gt;The port I used as a base already had an implementation of the SMC (System
Monitor Call) &lt;code&gt;PSCI_CPU_ON&lt;/code&gt; that made the secondary cores wait in a loop until
it was called, at which point it released them and jumped to the given address.&lt;/p&gt;
&lt;p&gt;Unfortunately, this can&amp;rsquo;t work with the kernel if it doesn&amp;rsquo;t know about PSCI,
and that was trickier that I expected. In the end, I decided to simply add some
glue code by creating a small bootstrap that would be used as BL33 image and run
in EL2. It would act like a really simple UEFI or U-Boot. The idea is to use
this bootstrap to release the locks from the firmware by calling &lt;code&gt;PSCI_CPU_ON&lt;/code&gt;
and make them wait in a wait loop that uses the mailbox that Raspbian knows how
to use to boot the secondary cores. I didn&amp;rsquo;t really know how to do this, so I
just checked how it is done in the official distribution of Raspbian. The
following 2 links contain the bootstraps for a 32-bit kernel and a 64-bit kernel
respectively:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/raspberrypi/tools/blob/master/armstubs/armstub7.S&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/raspberrypi/tools/blob/master/armstubs/armstub7.S&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/raspberrypi/tools/blob/master/armstubs/armstub8.S&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/raspberrypi/tools/blob/master/armstubs/armstub8.S&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;armstub7.S&lt;/code&gt; is used by the Raspberry Pi 2, which has 4 Cortex-A7, but also by
the Raspberry Pi 3 when booting a 32-bit kernel, and it has 4 Cortex-A53.
&lt;code&gt;armstub8.S&lt;/code&gt; is used by the Raspberry Pi 3 when booting a 64-bit kernel. The
compiled bootstraps are embedded on one of the elf files that are loaded by the
VideoCore at boot.&lt;/p&gt;
&lt;p&gt;After some reverse engineering I created my own versions of the bootstraps:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/rpi3-arm-tf-bootstrap&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/rpi3-arm-tf-bootstrap&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As a side effect of my reverse engineering efforts, I checked the Technical
Reference Manuals of the Cortex-A53 and Cortex-A7 and found some really small
bugs in the official bootstrap for the 32-bit kernel. I created a pull request
to fix them:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/raspberrypi/tools/pull/85&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/raspberrypi/tools/pull/85&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However&amp;hellip; After all that effort, the secondary cores still refused to work. I
decided to resort to printf-powered debugging and found out that the cores were
actually crashing before the kernel had had the chance to claim them. It took me
some time to understand the reason. Again, &lt;code&gt;Documentation/arm/Booting&lt;/code&gt; had the
answer: The kernel copies itself to a different memory region at boot:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The zImage may also be placed in system RAM and called there. The kernel
should be placed in the first 128MiB of RAM. It is recommended that it is
loaded above 32MiB in order to avoid the need to relocate prior to
decompression, which will make the boot process slightly faster.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;During this copy, the code of my waitloop was being overwritten. I checked that
moving the firmware to a location far away fixed the problem, but now I really
needed to find a way to protect he memory region used by the firmware. The whole
point of BL31 is to have some services that can be used by the operating system.
If Linux is free to use the memory used by the firmware, this can&amp;rsquo;t work.&lt;/p&gt;
&lt;p&gt;I eventually found out the solution: To add &lt;code&gt;memmap=256M$16M&lt;/code&gt; to the file
&lt;code&gt;cmdline.txt&lt;/code&gt;. This option tells the kernel that at the address 256 MiB there
are 16 MiB that it shouldn&amp;rsquo;t use, even if that range of memory contains valid
ram specified in the device tree that tells it about all the hardware in the
system.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NOTICE:  Booting Trusted Firmware
NOTICE:  BL1: v1.4(debug):v1.4-308-g65c55091-dirty
NOTICE:  BL1: Built : 20:33:44, Nov  5 2017
NOTICE:  BL1: Booting BL2
NOTICE:  BL2: v1.4(debug):v1.4-308-g65c55091-dirty
NOTICE:  BL2: Built : 20:33:44, Nov  5 2017
NOTICE:  BL1: Booting BL31
NOTICE:  BL31: v1.4(debug):v1.4-308-g65c55091-dirty
NOTICE:  BL31: Built : 20:33:44, Nov  5 2017
[    0.266483] bcm2835-aux-uart 3f215040.serial: could not get clk: -517

Raspbian GNU/Linux 9 raspberrypi ttyS0
raspberrypi login: pi
Password:
Last login: Sun Nov  5 20:41:18 GMT 2017 on tty1
Linux raspberrypi 4.9.41-v7+ #1023 SMP Tue Aug 8 16:00:15 BST 2017 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
pi@raspberrypi:~$ cat /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 4 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva
idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 1
model name      : ARMv7 Processor rev 4 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva
idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 2
model name      : ARMv7 Processor rev 4 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva
idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 3
model name      : ARMv7 Processor rev 4 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva
idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

Hardware        : BCM2835
Revision        : a02082
Serial          : 000000001528876b
pi@raspberrypi:~$ sudo shutdown now
[   64.551587] reboot: Power down
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And a photo I took to commemorate the moment. :)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2018-02-01-port-arm-tf-to-rpi3/arm-tf-32-bit-kernel-multicore.jpg&#34;
	width=&#34;1040&#34;
	height=&#34;780&#34;
	srcset=&#34;https://skylyrac.net/p/2018-02-01-port-arm-tf-to-rpi3/arm-tf-32-bit-kernel-multicore_hu_bc06c5d2b0a8a419.jpg 480w, https://skylyrac.net/p/2018-02-01-port-arm-tf-to-rpi3/arm-tf-32-bit-kernel-multicore_hu_924acfa753a3fc6e.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;At last, everything was working! Linux could detect all 4 cores! All I needed to
do now is to make sure that my port would also work with a 64-bit kernel, but&amp;hellip;
well, I didn&amp;rsquo;t have any 64-bit kernel and I didn&amp;rsquo;t know where to get one from. I
ended up compiling my own.&lt;/p&gt;
&lt;h2 id=&#34;getting-a-64-bit-kernel-to-work&#34;&gt;Getting a 64-bit kernel to work
&lt;/h2&gt;&lt;p&gt;It is really simple, actually, you just have to clone the
&lt;a class=&#34;link&#34; href=&#34;https://github.com/raspberrypi/linux&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Linux tree fork&lt;/a&gt; maintained by the
Raspberry Pi Foundation and compile it for 64-bit:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone --depth&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; -b rpi-4.14.y https://github.com/raspberrypi/linux
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; linux
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make &lt;span class=&#34;nv&#34;&gt;ARCH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;arm64 &lt;span class=&#34;nv&#34;&gt;CROSS_COMPILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;aarch64-linux-gnu- bcmrpi3_defconfig
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make -j &lt;span class=&#34;m&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ARCH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;arm64 &lt;span class=&#34;nv&#34;&gt;CROSS_COMPILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;aarch64-linux-gnu-
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Then, copy the kernel image and the device tree to the SD card.&lt;/p&gt;
&lt;p&gt;``sh
cp arch/arm64/boot/Image /path/to/boot/kernel8.img
cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /path/to/boot/&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
Finally, install the kernel modules.

```sh
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
    INSTALL_MOD_PATH=/path/to/filesystem modules_install
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I also had to create a bootstrap in a similar way as I did for the 32-bit
kernel. It was easier now, though. All the booting information is in the file
&lt;code&gt;Documentation/arm64/booting.txt&lt;/code&gt;, like with the 32-bit kernel.&lt;/p&gt;
&lt;p&gt;After a bit of work, I finally got the kernel booting and releasing all
secondary cores from their loops! The console output for this kernel, however,
is really verbose, so I&amp;rsquo;ve cut significant parts of it:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NOTICE:  Booting Trusted Firmware
NOTICE:  BL1: v1.4(debug):v1.4-331-gac96a37f
NOTICE:  BL1: Built : 22:59:37, Nov 13 2017
NOTICE:  BL1: Booting BL2
NOTICE:  BL2: v1.4(debug):v1.4-331-gac96a37f
NOTICE:  BL2: Built : 22:59:37, Nov 13 2017
NOTICE:  BL1: Booting BL31
NOTICE:  BL31: v1.4(debug):v1.4-331-gac96a37f
NOTICE:  BL31: Built : 22:59:37, Nov 13 2017
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.14.0-rc8-v8+ (antonio@antonio-debian-laptop)
(gcc version 7.1.1 20170707 (Linaro GCC 7.1-2017.08)) #1 SMP PREEMPT Sun Nov
12 19:55:59 GMT 2017
[    0.000000] Boot CPU: AArch64 Processor [410fd034]
[    0.000000] Machine model: Raspberry Pi 3 Model B Rev 1.2
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 8 MiB at 0x000000003ac00000
[    0.000000] random: fast init done
[    0.000000] percpu: Embedded 22 pages/cpu @ffffffe77ab7e000 s50456 r8192
d31464 u90112
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: enabling workaround for ARM erratum 845719
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 238896
[    0.000000] Kernel command line: 8250.nr_uarts=1 bcm2708_fb.fbwidth=656
bcm2708_fb.fbheight=416 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000
vc_mem.mem_size=0x40000000  dwc_otg.lpm_enable=0 console=ttyS0,115200
console=tty1 root=PARTUUID=5cd2ad4c-02 rootfstype=ext4 elevator=deadline
fsck.repair=yes rootwait memmap=256M$16M
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576
bytes)
[    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288
bytes)
[    0.000000] Memory: 930484K/970752K available (6972K kernel code, 884K
rwdata, 2304K rodata, 2624K init, 697K bss, 32076K reserved, 8192K
cma-reserved)

... several lines of output ...

[    0.012143] smp: Bringing up secondary CPUs ...
[    0.019337] Detected VIPT I-cache on CPU1
[    0.019402] CPU1: Booted secondary processor [410fd034]
[    0.026438] Detected VIPT I-cache on CPU2
[    0.026480] CPU2: Booted secondary processor [410fd034]
[    0.033553] Detected VIPT I-cache on CPU3
[    0.033594] CPU3: Booted secondary processor [410fd034]
[    0.033729] smp: Brought up 1 node, 4 CPUs
[    0.033857] SMP: Total of 4 processors activated.
[    0.033885] CPU features: detected feature: 32-bit EL0 Support
[    0.034111] CPU: All CPU(s) started at EL2
[    0.034160] alternatives: patching kernel code

... several lines of output ...

Raspbian GNU/Linux 9 raspberrypi ttyS0
raspberrypi login: pi

Password:
Last login: Thu Sep  7 16:23:37 UTC 2017 on ttyS0
Linux raspberrypi 4.14.0-rc8-v8+ #1 SMP PREEMPT Sun Nov 12 19:55:59 GMT 2017
aarch64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
pi@raspberrypi:~$ uname -a
Linux raspberrypi 4.14.0-rc8-v8+ #1 SMP PREEMPT Sun Nov 12 19:55:59 GMT 2017
aarch64 GNU/Linux
pi@raspberrypi:~$ cat /proc/cpuinfo
processor       : 0
BogoMIPS        : 38.40
Features        : fp asimd evtstrm crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 1
BogoMIPS        : 38.40
Features        : fp asimd evtstrm crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 2
BogoMIPS        : 38.40
Features        : fp asimd evtstrm crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 3
BogoMIPS        : 38.40
Features        : fp asimd evtstrm crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

pi@raspberrypi:~$ sudo shutdown now

... several lines of output ...

[   78.768742] reboot: Power down
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The final thing to do was to write the documentation of this port and to create
a pull request:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/ARM-software/arm-trusted-firmware/pull/1157&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/ARM-software/arm-trusted-firmware/pull/1157&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It was reviewed and merged, and now the Trusted Firmware-A has an upstream port
for the Raspberry Pi 3! It was a pretty interesting project, I learned a lot
about the Linux kernel boot process and about the kind of problems that people
that do the bringup of a platform have to face.&lt;/p&gt;
&lt;p&gt;I hope you found this article interesting!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2018-03-23)&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;The name of the project is &lt;strong&gt;Trusted Firmware-A&lt;/strong&gt;. All references to &lt;strong&gt;Arm
Trusted Firmware&lt;/strong&gt; have been replaced by the new name.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>µCity v1.2</title>
        <link>https://skylyrac.net/p/2018-01-31-ucity-v1-2/</link>
        <pubDate>Wed, 31 Jan 2018 02:10:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2018-01-31-ucity-v1-2/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2018-01-31-ucity-v1-2/ucity-screenshot.png" alt="Featured image of post µCity v1.2" /&gt;&lt;p&gt;Hello again!&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a bit late to publish this, but hey, it only comes 7 months late! I had no
website to upload this to, anyway&amp;hellip;&lt;/p&gt;
&lt;p&gt;In any case, here it is, &lt;strong&gt;µCity&lt;/strong&gt;, the  open-source city-building game for Game
Boy Color! It can also be spelled &amp;lsquo;uCity&amp;rsquo;, but it&amp;rsquo;s pronounced &amp;lsquo;micro-city&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2018-01-31-ucity-v1-2/ucity-screenshot.png&#34;
	width=&#34;480&#34;
	height=&#34;432&#34;
	srcset=&#34;https://skylyrac.net/p/2018-01-31-ucity-v1-2/ucity-screenshot_hu_dadba1a135e4022c.png 480w, https://skylyrac.net/p/2018-01-31-ucity-v1-2/ucity-screenshot_hu_b28886f5c88d70f6.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;This game is completely free, licensed under the GPLv3+. Just download the ROM,
install a Game Boy Color emulator, and play! The last release of the game should
be here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/ucity/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/ucity/releases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also play on real hardware. Even though the game has been developed
using mainly emulators, it has been verified to work on hardware. The game
detects how much available space there is and adjust the maximum number of saved
cities accordingly.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=2rir-TVx020&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;video&lt;/a&gt;, in case you are
too lazy to test the ROM. If needed, there is a short manual with instructions
for the player in the file &lt;code&gt;manual.rst&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been asked quite a few times about this, so I might as well clarify it. A
direct port of this game to the monochrome Game Boy isn&amp;rsquo;t possible. This game
uses most of the extra RAM that was added to the Game Boy Color, which isn&amp;rsquo;t
available in a regular Game Boy. While the Game Boy Color has 32 KiB of WRAM,
the Game Boy only has 8 KB, and this game currently uses 30 KB more or less.
Only a really limited version of this game with a much smaller map and much
fewer features would fit in a Game Boy.&lt;/p&gt;
&lt;p&gt;Oh, and this game has its own article in Hackaday!&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://hackaday.com/2017/06/20/writing-a-new-game-for-the-game-boy-color/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://hackaday.com/2017/06/20/writing-a-new-game-for-the-game-boy-color/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to actually take a look at it, the
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/ucity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;source code is available here&lt;/a&gt;. An
open-source project is a lot worse without documentation, though! That&amp;rsquo;s why the
code has a lot of comments and why there is a highly detailed documentation in
the &lt;code&gt;docs&lt;/code&gt; folder. And also because assembly code without comments can&amp;rsquo;t be
understood even by the developer who wrote it originally. :) To compile it,
you&amp;rsquo;ll just need &lt;a class=&#34;link&#34; href=&#34;https://github.com/gbdev/rgbds&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RGBDS&lt;/a&gt;. It should be possible
to compile the game on Linux, MinGW, Cygwin, etc.&lt;/p&gt;
&lt;p&gt;Other tools used to create the game are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://openmpt.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Open ModPlug Tracker&lt;/a&gt;: This is just a program to edit
tracker style music. It has been used to compose the music used by GBT Player,
my music player library. It can be found &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/gbt-player&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.devrs.com/gb/hmgd/gbtd.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBTD&lt;/a&gt; (Game Boy Tile Designer) and
&lt;a class=&#34;link&#34; href=&#34;http://www.devrs.com/gb/hmgd/gbmb.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBMB&lt;/a&gt; (Game Boy Map Builder):
Graphics edition tools (for Windows, but they run on Wine).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;beware: For the emulator &lt;a class=&#34;link&#34; href=&#34;http://bgb.bircd.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;BGB&lt;/a&gt;, extremely useful tool
used to develop this game.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pan of Anthrox, Marat Fayzullin, Pascal Felber, Paul Robson, Martin Korth
(nocash) and kOOPa for the pandocs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Otaku No Zoku (Justin Lloyd) for the Gameboy Crib Sheet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Everyone that has contributed to develop &lt;code&gt;RGBDS&lt;/code&gt; over the years, specially
Carsten Sorensen, Justin Lloyd, Vegard Nossum and Anthony J. Bentley.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PS: If the name of the game breaks your website, fix your website. :P&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from &lt;a class=&#34;link&#34; href=&#34;https://github.com/AntonioND/ucity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub&lt;/a&gt; to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Welcome to my new blog!</title>
        <link>https://skylyrac.net/p/2018-01-29-welcome/</link>
        <pubDate>Mon, 29 Jan 2018 01:54:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2018-01-29-welcome/</guid>
        <description>&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;After almost a year of having my website down, I decided it was time to do
something about it! This is my attempt at creating a new website.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m using &lt;a class=&#34;link&#34; href=&#34;https://github.com/getpelican/pelican&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Pelican&lt;/a&gt;. Let&amp;rsquo;s see how code
looks like, for example&amp;hellip;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;cm&#34;&gt;/* Print string */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Hello, world!&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;It will take some time to create articles about my latest projects, and I&amp;rsquo;ve
reuploaded all the entries of my old blog and website!&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/old-site/index.html&#34; &gt;Old website&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, this change means that any comment left on my old blog will be
lost, but well, there weren&amp;rsquo;t that many&amp;hellip;&lt;/p&gt;
&lt;p&gt;Antonio&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Geometrix [GBC Game][GBDev 2015]</title>
        <link>https://skylyrac.net/p/2015-12-04-geometrix-gbc-game-gbdev-2015/</link>
        <pubDate>Fri, 04 Dec 2015 16:32:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2015-12-04-geometrix-gbc-game-gbdev-2015/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2015-12-04-geometrix-gbc-game-gbdev-2015/geometrix.png" alt="Featured image of post Geometrix [GBC Game][GBDev 2015]" /&gt;&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;This is my entry for the
&lt;a class=&#34;link&#34; href=&#34;http://gbdev.gg8.se/forums/viewtopic.php?pid=1385&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBdev Game Boy Coding Compo 2015&lt;/a&gt;!
Sadly, &lt;a class=&#34;link&#34; href=&#34;http://gbdev.gg8.se/forums/viewtopic.php?pid=1448&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;only one more game entered the compo&lt;/a&gt;.
But anyway, here it is!&lt;/p&gt;
&lt;p&gt;Video: &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=qAvW2n8Qbeg&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.youtube.com/watch?v=qAvW2n8Qbeg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Source, binary and more information:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/geometrix&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/geometrix&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Screenshots:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-12-04-geometrix-gbc-game-gbdev-2015/geometrix.png&#34;
	width=&#34;660&#34;
	height=&#34;596&#34;
	srcset=&#34;https://skylyrac.net/p/2015-12-04-geometrix-gbc-game-gbdev-2015/geometrix_hu_3dd236e26f9106d4.png 480w, https://skylyrac.net/p/2015-12-04-geometrix-gbc-game-gbdev-2015/geometrix_hu_b3d8065d58b2ac9f.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;110&#34;
		data-flex-basis=&#34;265px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Tetris made with a PIC18F2550</title>
        <link>https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/</link>
        <pubDate>Sun, 20 Sep 2015 23:06:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-front.jpg" alt="Featured image of post Tetris made with a PIC18F2550" /&gt;&lt;p&gt;Hello again!&lt;/p&gt;
&lt;p&gt;This time I&amp;rsquo;m writing to show you my newest electronic creation: a &amp;ldquo;videogame
console&amp;rdquo; made with a &lt;strong&gt;PIC18F2550&lt;/strong&gt; as its brain. It has a 8x16 LED matrix as
main display and 4 seven segment displays to show the player score, for example.
It has 8 buttons (4 in a pad, the rest like a Game Boy or similar). The PIC
doesn&amp;rsquo;t have enough pins to control everything easily, so I&amp;rsquo;ve used a few
74HC595 to control the LED matrix and the seven segment displays, and a 74HC166
to read the state of all buttons.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-front.jpg&#34;
	width=&#34;612&#34;
	height=&#34;816&#34;
	srcset=&#34;https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-front_hu_35a12107ba1d6aa4.jpg 480w, https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-front_hu_1c159ef0b79cd9b7.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;75&#34;
		data-flex-basis=&#34;180px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-back.jpg&#34;
	width=&#34;612&#34;
	height=&#34;816&#34;
	srcset=&#34;https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-back_hu_5d0a96b4c63bf3bd.jpg 480w, https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-back_hu_1fe21121f9a67b30.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;75&#34;
		data-flex-basis=&#34;180px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;The game I&amp;rsquo;ve decided to code for the demonstration is a simple Tetris, written
in 100% assembly. YouTube &lt;strong&gt;video&lt;/strong&gt; here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=5fmSbreJsDI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.youtube.com/watch?v=5fmSbreJsDI&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Buttons&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Move left/right.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rotate clockwise/counterclockwise.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go down quickly, go down instantly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pause, reset.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the moment I haven&amp;rsquo;t decided if I should post the schematics and the source
code for various reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I used different systems to power the LED matrix and the seven segment
displays. A decent design should use the same system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some resistors are too high and the LEDs, when lit, are too dim. I didn&amp;rsquo;t
consider the scanline refresh when calculating the resistors, so the actual
intensity is a lot lower than I thought.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The source code of the game is a bit messy (the &amp;ldquo;drivers&amp;rdquo; code is good,
though).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Well, I hope you like it!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt;: Well, whatever, I&amp;rsquo;ll just put the schematics and the code&amp;hellip; :P&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schematics&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-sch.png&#34;
	width=&#34;2161&#34;
	height=&#34;1532&#34;
	srcset=&#34;https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-sch_hu_240e51e443f97971.png 480w, https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-sch_hu_b67ff9a3faab01d7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;141&#34;
		data-flex-basis=&#34;338px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-sch-bw.png&#34;
	width=&#34;2161&#34;
	height=&#34;1532&#34;
	srcset=&#34;https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-sch-bw_hu_8b5971426a14d882.png 480w, https://skylyrac.net/p/2015-09-20-tetris-made-with-a-pic18f2550/tetris-pic-sch-bw_hu_7c3a280b7c95f4e6.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;141&#34;
		data-flex-basis=&#34;338px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t expect it to be clean and/or human readable. The file &amp;lsquo;main.asm&amp;rsquo; contains
the &amp;lsquo;drivers&amp;rsquo;, and &amp;rsquo;tetris.asm&amp;rsquo; contains the game. It&amp;rsquo;s fairly easy to modify it
to change some of the pin assignments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Download (gEDA schematics + assembly code + assembled .hex file)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;New version (2015/10/06), with a small modification to prevent &amp;ldquo;ghosting&amp;rdquo;
between displays when performing the scanline change. Also fixed a bug that
didn&amp;rsquo;t remove completed lines before checking if game over.&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/tetris_pic_20151006.tar.gz&#34; &gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Possible improvements&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Change pull-down resistors for the buttons (R29-R36) by 10K resistors.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change LED resistors (330 Ohm) by 300 or maybe 220 resistors (R1-R16 and
R37-R44).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make the LED matrix and the seven segment displays work the same way (changing
the displays by common-anode equivalents and the transistors used to drive
them).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Electronic dice</title>
        <link>https://skylyrac.net/p/2015-07-12-electronic-dice/</link>
        <pubDate>Sun, 12 Jul 2015 20:15:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2015-07-12-electronic-dice/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-1.jpg" alt="Featured image of post Electronic dice" /&gt;&lt;p&gt;Well, after a few weeks not doing almost anything I&amp;rsquo;ve decided to post the last
useless device I&amp;rsquo;ve made. It&amp;rsquo;s a simple electronic dice using a decade counter
and some inverters (used for logic and as oscillator). I decided not to use a
microcontroller because it felt like it was cheating for a circuit this
simple&amp;hellip; There&amp;rsquo;s not much to say: pressing the button will enable the counter
and releasing the button will stop it and show a &amp;ldquo;random&amp;rdquo; number. The counter is
very fast so it&amp;rsquo;s impossible to guess what number is going to show when the
button is released. Here are a few pictures:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-1.jpg&#34;
	width=&#34;816&#34;
	height=&#34;612&#34;
	srcset=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-1_hu_7ae89d6e641afb60.jpg 480w, https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-1_hu_2d1ff3d2e3df545f.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-2.jpg&#34;
	width=&#34;816&#34;
	height=&#34;612&#34;
	srcset=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-2_hu_13c1dcc305875421.jpg 480w, https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-2_hu_b64c2582ce3c9f0a.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;I used foam to hold the board and the battery in place so that it could be put
into a handmade box.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-3.jpg&#34;
	width=&#34;816&#34;
	height=&#34;612&#34;
	srcset=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-3_hu_af558863e9081671.jpg 480w, https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-3_hu_7eece0f3dbfe1c97.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-4.jpg&#34;
	width=&#34;816&#34;
	height=&#34;612&#34;
	srcset=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-4_hu_14aee6ff5f87dfb7.jpg 480w, https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-4_hu_3baca3c8b1c736ea.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;And, at last, a video of the circuit working:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=t7blrTmsfKg&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.youtube.com/watch?v=t7blrTmsfKg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While it&amp;rsquo;s a really simple circuit to design and make, I&amp;rsquo;ve decided to create
schematics in case someone wants to make this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-schematics.png&#34;
	width=&#34;2760&#34;
	height=&#34;1377&#34;
	srcset=&#34;https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-schematics_hu_fb6a7754ead14120.png 480w, https://skylyrac.net/p/2015-07-12-electronic-dice/electronic-dice-schematics_hu_8b762c4f228a809b.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;200&#34;
		data-flex-basis=&#34;481px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Almost all components are specified in the schematic. The ones that aren&amp;rsquo;t
completely specified are the voltage regulator (78L05), the inverter IC (74LS04)
and the decade counter (HFC4017).&lt;/p&gt;
&lt;p&gt;There are two interesting things about this circuit, and the reason of both of
them is that I didn&amp;rsquo;t want to buy many components, so I decided to use whatever
I had at home:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The first one is that the oscillator is made of two inverters (and a capacitor
and resistor). The values I&amp;rsquo;ve used for R and C make it oscillate at 390Hz
approximately.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The second one is that I don&amp;rsquo;t use an IC with OR gates. I&amp;rsquo;ve decided to use
some diodes and resistors to create them
(&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Diode_logic%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://en.wikipedia.org/wiki/Diode_logic)&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The circuit uses a 9 V battery. The logic of the circuit needs about 11 mA, and
the LEDs need around 9 mA each. That means it uses from 20 mA (when only 1 LED
is on) to 65 mA (when 6 LEDs are on). The 7 LEDs can&amp;rsquo;t be turned on at the same
time, obviously.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GBT Player usage</title>
        <link>https://skylyrac.net/p/2015-04-08-gbt-player-usage/</link>
        <pubDate>Wed, 08 Apr 2015 01:36:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2015-04-08-gbt-player-usage/</guid>
        <description>&lt;p&gt;Over the last months I&amp;rsquo;ve seen a few tutorials about GB programming that use my
GBT Player for music. I have to say a few things about that.&lt;/p&gt;
&lt;p&gt;First: Thanks a lot for using my library! The fact that you like it enough to
use it in your projects is what keeps it alive. Version 2 only happened because
I was asked to add a few things to previous versions.&lt;/p&gt;
&lt;p&gt;Second: &lt;strong&gt;You are using it wrong!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ok, it&amp;rsquo;s partly my fault, but it&amp;rsquo;s your fault too, obviously: &lt;em&gt;You are using
GBDK&lt;/em&gt;&amp;hellip; I mean, you just don&amp;rsquo;t understand the implications of the ROM banking
system the GB uses. I know I don&amp;rsquo;t really have to explain this kind of things,
but I feel a bit responsible for my library, so I&amp;rsquo;m going to explain why you are
using it wrong and how to fix it. Let&amp;rsquo;s see&amp;hellip;&lt;/p&gt;
&lt;p&gt;My (now old) example does something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;gb/gb.h&amp;gt; // Include GBDK lib&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;#34;gbt_player.h&amp;#34; // Include player&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Reference to song data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;song_Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Disable interrupts while they are being configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;disable_interrupts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;gbt_play&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;song_Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Setup song
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;gbt_loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// The default is 0, this could be removed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;add_VBL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gbt_update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Add callback for VBL interrupt (*)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;set_interrupts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;VBL_IFLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Enable VBL interrupt
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;enable_interrupts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;wait_vbl_done&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Wait loop with reduced CPU usage
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;While the new one does this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;gb/gb.h&amp;gt; // Include GBDK lib&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;#34;gbt_player.h&amp;#34; // Include player&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Reference to song data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;song_Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Disable interrupts while they are being configured
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;disable_interrupts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;gbt_play&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;song_Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Setup song
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;gbt_loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// The default is 0, this could be removed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;set_interrupts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;VBL_IFLAG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Enable VBL interrupt
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;enable_interrupts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;wait_vbl_done&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Wait loop with reduced CPU usage
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;gbt_update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Update player (*)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;So what&amp;rsquo;s the big deal?&lt;/p&gt;
&lt;p&gt;Well, let&amp;rsquo;s explain how the GB banking system works. You should know that. If
you don&amp;rsquo;t know that, you shouldn&amp;rsquo;t be coding for GB, but whatever&amp;hellip; The first
16 KB of the ROM are always mapped to addresses &lt;code&gt;0000h-3FFFh&lt;/code&gt;. This means that
this code and data is always available to read! That&amp;rsquo;s the place where you want
your game engine to be. But GBT code doesn&amp;rsquo;t go there by default. It goes to
bank 1. Why? Because 16 KB is not much space. GBT player needs quite a bit of
space and it&amp;rsquo;s stupid to put it in bank 0 when GBDK is already using a lot of
that space. It would leave you even less space for your code!&lt;/p&gt;
&lt;p&gt;Banks 1 and beyond are mapped to addresses &lt;code&gt;4000h-7FFFh&lt;/code&gt;. Only one of them can
be mapped at once there, so they must be switched when the program needs to
access to data in other bank. This means that you can have as much 16 KB banks
as you need (so you could have ROMs with &lt;em&gt;infinite&lt;/em&gt; banks), but you have to take
care to switch to the correct bank whenever you are trying to get some data or
execute some code.&lt;/p&gt;
&lt;p&gt;So GBT runs in bank 1, again, what&amp;rsquo;s the big deal?&lt;/p&gt;
&lt;p&gt;The problem here is that the first example uses interrupt for the player update
function. If your game loop is small, and your ROM is small, and your game is
more or less a &amp;ldquo;Hello World!&amp;rdquo; this won&amp;rsquo;t be a problem because you won&amp;rsquo;t use bank
switching and bank 1 will always be available. If your game is big and you need
to load data from other banks, there are problems because you will sometimes use
data from other banks (in fact, GBT Player loads data from the bank where the
song is placed, but it returns to bank 1 afterwards to execute its code).&lt;/p&gt;
&lt;p&gt;An interrupt means that the CPU jumps to an interrupt vector, executes its code
and then returns to its previous state. Again, you should know that. If you
don&amp;rsquo;t, something is wrong and you should stop and learn this kind of things
first. But you won&amp;rsquo;t, that&amp;rsquo;s why I&amp;rsquo;m explaining this. This is useful to know
when hardware events happen, like screen redraw. Vertical blanking period is
entered when the current frame has been drawn, so it happens once every frame
(around 60 times per second). This interrupt is very useful to synchronize the
game, and GBT Player uses it to update itself.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say you want to load a background placed in bank 4. You switch to bank 4,
start copying&amp;hellip; and vertical blank period is reached. An interrupt is triggered
and CPU jumps to the VBL interrupt vector at address &lt;code&gt;0040h&lt;/code&gt;. It eventually
calls &lt;code&gt;gbt_update()&lt;/code&gt;, which switches to bank 1, and returns. The CPU returns
to the same state as before the interrupt&amp;hellip; but the ROM bank is still bank 1,
so the copy won&amp;rsquo;t work because it&amp;rsquo;s reading incorrect data! This can also happen
with code. In that case, the game is likely to crash immediately. If you only
had banks 0 and 1, this couldn&amp;rsquo;t happen. That&amp;rsquo;s why small demos and games run
fine, but they will eventually crash if they are more than 32 KB big (2 banks).&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why the code of &lt;code&gt;gbt_player.h&lt;/code&gt; says &amp;ldquo;this changes to bank 1!&amp;rdquo;. To warn
you that this does changes to the memory that you have to revert. I don&amp;rsquo;t know
what system GBDK uses to know what ROM bank is being used or anything like that.
When I made a game (that I didn&amp;rsquo;t finish) I created a ROM bank stack to keep
track of the banks that I used, so I could save the bank that was being used
when &lt;code&gt;gbt_update()&lt;/code&gt; was called and I could restore it afterwards. I suppose
most of you won&amp;rsquo;t be able to do something like that, so the new example is an
alternative.&lt;/p&gt;
&lt;p&gt;The new example calls &lt;code&gt;gbt_update()&lt;/code&gt; every frame in the main loop of the game.
You need to put it in EVERY main loop, and you need to synchronize the game to
VBL with &lt;code&gt;wait_vbl_done()&lt;/code&gt;. That&amp;rsquo;s it. No more problems of banking. Well,
there still can be problems, but it&amp;rsquo;s more difficult. If you can write code that
has that kind of problems, you should be able to fix them.&lt;/p&gt;
&lt;p&gt;In fact, if your game doesn&amp;rsquo;t use &lt;code&gt;wait_vbl_done()&lt;/code&gt;, your game is evil. This
function enters a low consumption state until VBL is entered, and it should be
used whenever it&amp;rsquo;s possible. I&amp;rsquo;ve seen code of &amp;ldquo;games&amp;rdquo; that don&amp;rsquo;t use it. They
are bad. No, seriously, use that function. Please.&lt;/p&gt;
&lt;p&gt;Examples of bad tutorials (I could only find 2 right now, both in Spanish):&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.elotrolado.net/hilo_desarrollo-software-proyectos-de-darkryoga_1901847&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.elotrolado.net/hilo_desarrollo-software-proyectos-de-darkryoga_1901847&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.fasebonus.net/foro/index.php?topic=36662.msg60626#msg60626&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.fasebonus.net/foro/index.php?topic=36662.msg60626#msg60626&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PS: But you are, in fact, using GBDK, which should be avoided. :P It&amp;rsquo;s better if
you try to learn ASM and use RGBDS or WLA-DX assemblers instead. The GB CPU is
very slow, so you need every CPU cycle you can get. Maybe you are doing a
text-only game, and then GBDK should be fine, but you are wasting a lot of CPU
power. GBDK functions are mostly written in ASM. I know it&amp;rsquo;s harder and you want
to see results right now, but it&amp;rsquo;s better.&lt;/p&gt;
&lt;p&gt;PS2: Anyway, update to the latest version (2.1.1 at the time of writing this,
the same as 2.1.0 but with a new GBDK example):&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/gbt-player&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/gbt-player&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Game Boy Camera documentation</title>
        <link>https://skylyrac.net/p/2015-03-12-game-boy-camera-documentation/</link>
        <pubDate>Thu, 12 Mar 2015 13:20:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2015-03-12-game-boy-camera-documentation/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2015-03-12-game-boy-camera-documentation/gbcam-arduino.jpg" alt="Featured image of post Game Boy Camera documentation" /&gt;&lt;p&gt;Over the last few weeks I&amp;rsquo;ve been doing some reverse engineering on the GB
Camera and I think I&amp;rsquo;ve documented it good enough for most things. I&amp;rsquo;ve reversed
the cartridge controller registers and measured the capture timings. The only
thing that I can&amp;rsquo;t understand is the level/gain control of the sensor (its
datasheet is really bad) but it shouldn&amp;rsquo;t matter for an emulator. I&amp;rsquo;ve
implemented this in &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/giibiiadvance&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GiiBiiAdvance&lt;/a&gt;
and it&amp;rsquo;s working perfectly (you&amp;rsquo;ll have to wait for the next version if you want
to check it, though), so I guess that&amp;rsquo;s all that matters.&lt;/p&gt;
&lt;p&gt;And a pic of my hardware setup (click to zoom):&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-03-12-game-boy-camera-documentation/gbcam-arduino.jpg&#34;
	width=&#34;972&#34;
	height=&#34;732&#34;
	srcset=&#34;https://skylyrac.net/p/2015-03-12-game-boy-camera-documentation/gbcam-arduino_hu_979451ceb58b37e.jpg 480w, https://skylyrac.net/p/2015-03-12-game-boy-camera-documentation/gbcam-arduino_hu_3a36bb71eda58bd0.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;132&#34;
		data-flex-basis=&#34;318px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;The repository is here: &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/gbcam-rev-engineer&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/gbcam-rev-engineer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The first release is here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/gbcam-rev-engineer/releases/tag/v1.0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/gbcam-rev-engineer/releases/tag/v1.0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PS: Did I mention before that I won the GBdev 2014 compo?&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://gbdev.gg8.se/forums/viewtopic.php?id=244&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://gbdev.gg8.se/forums/viewtopic.php?id=244&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Pong 3DS v1.0</title>
        <link>https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/</link>
        <pubDate>Wed, 18 Feb 2015 00:21:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-2.png" alt="Featured image of post Pong 3DS v1.0" /&gt;&lt;p&gt;Well, after a few weeks of coding at last I have a release of this game. :)&lt;/p&gt;
&lt;p&gt;This is just a 3D pong, inspired by my old
&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/old-site/pong3ds.html&#34; &gt;Pong 3DS for Nintendo DS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This was a test to see if I could manage to setup a correct perspective for
stereoscopic 3D, but I decided to make a simple game out of it.&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t used hardware accelerated graphics because I couldn&amp;rsquo;t manage to
compile any shader assembler (except from Picasso, but it&amp;rsquo;s a bit outdated). I
originally made this 3D software engine for GBA, so there are still a few files
from Tonc&amp;rsquo;s library for GBA. Anyway, this game always runs at 60 FPS. :)&lt;/p&gt;
&lt;p&gt;If anyone cares, the 3D engine can draw lines, triangles, quads, line strips,
triangle strips and quad strips, all of them With alpha blending. Quads are
drawn using a function used just for them to draw them faster, not by drawing
two triangles. It supports directional lighting (up to 32 lights, limited to 2
because why more) and ambient lighting. It can sort polygons with painter&amp;rsquo;s
algorithm (no buffer-Z). It doesn&amp;rsquo;t support textured polygons.&lt;/p&gt;
&lt;p&gt;Oh, the 3D slider actually does something when you change its position. The
engine renders each top screen in a separate core when working in 3D mode to
make it run always at the same FPS.&lt;/p&gt;
&lt;p&gt;Press Y to take a screenshot in PNG format (2 files in 3D mode, 1 in 2D mode) or
SELECT to exit. Use the joystick to move the pad, and A to jump in the 2.5D
room.&lt;/p&gt;
&lt;p&gt;For now, in the main menu, press a button in the touchscreen to enter a game
room. Pressing START in a room will return the game to the main menu.&lt;/p&gt;
&lt;p&gt;Holding L and R at the same time will show the FPS and the CPU usage.&lt;/p&gt;
&lt;p&gt;This game is licensed under the GPL Version 3.&lt;/p&gt;
&lt;p&gt;Binaries here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/pong-3ds/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/pong-3ds/releases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Source code and more information here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/pong-3ds&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/pong-3ds&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And a few screenshots:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-1.png&#34;
	width=&#34;400&#34;
	height=&#34;240&#34;
	srcset=&#34;https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-1_hu_d5f4d90722373c65.png 480w, https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-1_hu_2ed147f5779a631b.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;166&#34;
		data-flex-basis=&#34;400px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-2.png&#34;
	width=&#34;400&#34;
	height=&#34;240&#34;
	srcset=&#34;https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-2_hu_5ea678642fe66b8f.png 480w, https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-2_hu_fa9b910c1c431d75.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;166&#34;
		data-flex-basis=&#34;400px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-3.png&#34;
	width=&#34;400&#34;
	height=&#34;240&#34;
	srcset=&#34;https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-3_hu_778e81f68fcc381.png 480w, https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-3_hu_b5f8f9ffec9f243a.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;166&#34;
		data-flex-basis=&#34;400px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-4.png&#34;
	width=&#34;400&#34;
	height=&#34;240&#34;
	srcset=&#34;https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-4_hu_9b7d0b395b59356e.png 480w, https://skylyrac.net/p/2015-02-18-pong-3ds-v1-0/pong-3ds-screenshot-4_hu_b7cf4e20b5dee7f0.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;166&#34;
		data-flex-basis=&#34;400px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Pong 3DS, now in an actual Nintendo 3DS!</title>
        <link>https://skylyrac.net/p/2015-01-24-pong-3ds-now-in-an-actual-n3ds/</link>
        <pubDate>Sat, 24 Jan 2015 17:16:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2015-01-24-pong-3ds-now-in-an-actual-n3ds/</guid>
        <description>&lt;p&gt;Ok, this has nothing to do with &lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/old-site/pong3ds.html&#34; &gt;this other game&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is just a stupid stereoscopic 3D software rendering test. Oh, the 3D slider
actually does something when you change its position.&lt;/p&gt;
&lt;p&gt;No screenshot because it&amp;rsquo;s just a bunch of wireframe boxes IN THREE DIMENSIONS.
Maybe next time.&lt;/p&gt;
&lt;p&gt;Link: &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/pong-3ds&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/pong-3ds&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2015-01-25)&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Well, I&amp;rsquo;ve updated it a bit. Filled polygons, lighting, &lt;strong&gt;screenshots&lt;/strong&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2015-01-24-pong-3ds-now-in-an-actual-n3ds/pong-3ds-screenshot.png&#34;
	width=&#34;400&#34;
	height=&#34;240&#34;
	srcset=&#34;https://skylyrac.net/p/2015-01-24-pong-3ds-now-in-an-actual-n3ds/pong-3ds-screenshot_hu_5d333cb6808ad725.png 480w, https://skylyrac.net/p/2015-01-24-pong-3ds-now-in-an-actual-n3ds/pong-3ds-screenshot_hu_3e7f0f5d2ffb5179.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;166&#34;
		data-flex-basis=&#34;400px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Back to Color [GBC Demo][GBDev 2014]</title>
        <link>https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/</link>
        <pubDate>Mon, 30 Jun 2014 00:01:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/back_to_color_screenshots.png" alt="Featured image of post Back to Color [GBC Demo][GBDev 2014]" /&gt;&lt;p&gt;Hello again!&lt;/p&gt;
&lt;p&gt;This time I&amp;rsquo;m here to show you my first GBC demo! Made specially for the
&lt;a class=&#34;link&#34; href=&#34;http://gbdev.gg8.se/forums/viewtopic.php?id=173&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;2014 GBDev Game Boy Coding Compo&lt;/a&gt;.
In fact, I started it like four years ago, but stopped after doing 3 scenes (the
first effect, the text scroller at the end of the first song and the colorful
horizontal bars before the matrix effect). I&amp;rsquo;ve coded the rest in just a few
weeks, in fact I started doing new effects a few days before the GBDev compo
announcement. I&amp;rsquo;ve coded it and made the music, the only thing I haven&amp;rsquo;t done is
the train screen graphics and the credits graphics (by jordirafel). I&amp;rsquo;m not a
very good musician, so&amp;hellip; Oh, and it shows a little credits screen in non-color
GBs! Some screenshots here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/back_to_color_screenshots.png&#34;
	width=&#34;800&#34;
	height=&#34;432&#34;
	srcset=&#34;https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/back_to_color_screenshots_hu_a38eab097a812b54.png 480w, https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/back_to_color_screenshots_hu_414abd4b3a789ad7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;185&#34;
		data-flex-basis=&#34;444px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/back_to_color_dmg_screenshot.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/back_to_color_dmg_screenshot_hu_e3191beece59da3f.png 480w, https://skylyrac.net/p/2014-06-30-back-to-color-gbc-demo-gbdev-2014/back_to_color_dmg_screenshot_hu_adb13bba70be98cf.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;And here it is, the download link:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/back_to_color.zip&#34; &gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to test it in an emulator (like &lt;a class=&#34;link&#34; href=&#34;http://bgb.bircd.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;BGB&lt;/a&gt;,
&lt;a class=&#34;link&#34; href=&#34;http://sourceforge.net/projects/gambatte&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gambatte&lt;/a&gt; or &lt;a class=&#34;link&#34; href=&#34;http://vba-m.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VBA-M&lt;/a&gt;,
most of them have a &amp;ldquo;Frame Blending&amp;rdquo; option, enable it if possible. It works in
real hardware, of course! Tested in DMG, MGB, GBC, GBA and GBA SP. If you want
to skip some parts, hold up/right/down/left when the demo is loading if you want
to skip 1/2/3/4 songs. Non-color GB only show the reduced credits screen!&lt;/p&gt;
&lt;p&gt;I have also recorded a video with VBA-M in case you are too lazy to
download an emulator! :P The shadows in the bouncing balls effect are
incorrect, they should be the same color, but the rest is correct. In a
real GBC or an emulator it looks fine.&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=eSEsd1OGA74&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.youtube.com/watch?v=eSEsd1OGA74&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The demo has been coded using &lt;a class=&#34;link&#34; href=&#34;https://github.com/gbdev/rgbds&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;my fork of RGBDS&lt;/a&gt;
(with a few bugfixes), a &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/gbt-player&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBT Player&lt;/a&gt;
version modified to use only the first ROM bank, OpenMPT to make the music,
GBTK and GBMB. To test it I&amp;rsquo;ve used BGB, Gambatte, VBA-M, my
&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/giibiiadvance&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GiiBiiAdvance&lt;/a&gt;&amp;hellip; and real
hardware.&lt;/p&gt;
&lt;p&gt;I hope you like it! :)&lt;/p&gt;
&lt;p&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;Oh&amp;hellip;&lt;/p&gt;
&lt;p&gt;One last thing&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/back-to-color&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Source code&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yeah, that&amp;rsquo;s everything. :P&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2018-01-31)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This demo should be able to compile with the upstream RGBDS, located
&lt;a class=&#34;link&#34; href=&#34;https://github.com/gbdev/rgbds&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This demo is now hosted in &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/back-to-color&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Codeberg&lt;/a&gt;.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Faceball 2000 Double Speed Mod v0.1</title>
        <link>https://skylyrac.net/p/2014-06-04-faceball-2000-double-speed-mod-v0-1/</link>
        <pubDate>Wed, 04 Jun 2014 16:29:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2014-06-04-faceball-2000-double-speed-mod-v0-1/</guid>
        <description>&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;A few days ago I discovered this game, I tried it, and got disappointed because
it has a painfully low framerate &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=KQAhnNiOu54&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;video&lt;/a&gt;&amp;hellip;
So I opened it with BGB and decided to fix it! :)&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve changed the initial jump to an empty area just before the ROM header. I
just switch to CPU double speed mode, wait for VBL, load greyscale palettes for
BGs and sprites and jump to real start point. Of course, it only works in GBC
and GBA now! Header&amp;rsquo;s GBC flag has been changed, and checksums have been fixed.&lt;/p&gt;
&lt;p&gt;Just to make it clear: This makes the CPU faster, so everything changes. Music
is still the same because it uses interrupts for synchronization, framerate is
multiplied by at least 2, but timer countdown is affected! Also, link
communications are affected.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You&amp;rsquo;ll need an IPS patcher like &lt;a class=&#34;link&#34; href=&#34;http://www.romhacking.net/utilities/240&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Lunar IPS&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And, of course, the &amp;ldquo;Faceball 2000 (USA).gb&amp;rdquo; ROM, which I won&amp;rsquo;t provide here.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The patch you have to apply is here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/faceball_2000_gbc_mod_v01.ips&#34; &gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t tested Link functions, but it should work between modified copies of
the game. I haven&amp;rsquo;t changed the way the game works. It still copies VRAM data
manually instead of using GDMA or something like that, but that would need some
extra work, and it runs fine now. I hope you like it!&lt;/p&gt;
&lt;p&gt;Bye!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GBT Player v1.2</title>
        <link>https://skylyrac.net/p/2014-05-01-gbt-player-v1-2/</link>
        <pubDate>Thu, 01 May 2014 15:36:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2014-05-01-gbt-player-v1-2/</guid>
        <description>&lt;p&gt;Hello again!&lt;/p&gt;
&lt;p&gt;This is just a bugfix release. I&amp;rsquo;ve modified the samples included in the mod
file in order to avoid transposing notes when converting it with mod2gbt. This
means that you can use all notes from C3 to B8.&lt;/p&gt;
&lt;p&gt;You can find source, binaries and examples (RGBDS and GBDK) for version 1.2
here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/gbt-player/releases/tag/v1.2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/gbt-player/releases/tag/v1.2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And any other improvements, here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/gbt-player&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/gbt-player&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bye!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Switch GBA into GBC mode by software</title>
        <link>https://skylyrac.net/p/2014-04-20-switch-gba-into-gbc-mode-by-software/</link>
        <pubDate>Sun, 20 Apr 2014 20:46:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2014-04-20-switch-gba-into-gbc-mode-by-software/</guid>
        <description>&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;I know dwedit did something like this a few years ago, but I never managed to
compile its code and make it run (even though the precompiled binary worked
fine). Anyway, the code was incomprehensible:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.dwedit.org/dwedit_board/viewtopic.php?id=339&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.dwedit.org/dwedit_board/viewtopic.php?id=339&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This morning I&amp;rsquo;ve read that the GBA bios still had the piece of code that
switches the GBA into GBC mode, like Nintendo planned to do in the beginning
(before deciding that it would be better to do it with a hardware switch).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve disassembled the part that performs this switch and made a little demo to
show that it works! Here it is:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/gba-switch-to-gbc&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/gba-switch-to-gbc&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But it doesn&amp;rsquo;t end here! It can also apply an affine transformation to the GBC
video output, and even enable mosaic effect or &lt;code&gt;GREENSWP&lt;/code&gt; register! The
&lt;code&gt;GREENSWP&lt;/code&gt; register works a bit different than in GBA mode, by the way.&lt;/p&gt;
&lt;p&gt;The bad thing is that the video output only works in GB Micro, in GBA and GBA SP
it shows a black screen, and in DS it doesn&amp;rsquo;t work at all (it doesn&amp;rsquo;t have a GB
CPU).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve also uploaded a video:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=-SkR8SAdS9w&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.youtube.com/watch?v=-SkR8SAdS9w&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bye!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GiiBiiAdvance 0.2.0</title>
        <link>https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/</link>
        <pubDate>Fri, 04 Apr 2014 12:43:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-4.png" alt="Featured image of post GiiBiiAdvance 0.2.0" /&gt;&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;After a few years, at last I continue with this emulator. :P I&amp;rsquo;ve been coding
for a few weeks and at last I have a release.&lt;/p&gt;
&lt;p&gt;The main change is that it now uses SDL2 for the GUI, not WinAPI. It can compile
under Windows or Linux with the included Code::Blocks project file (I want to
add a Makefile later). You can check the source code here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/giibiiadvance&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/giibiiadvance&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some screen captures:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-1.png&#34;
	width=&#34;528&#34;
	height=&#34;486&#34;
	srcset=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-1_hu_68f42c9a14e43d6d.png 480w, https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-1_hu_6374d8ac7c0daba9.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;108&#34;
		data-flex-basis=&#34;260px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-2.png&#34;
	width=&#34;528&#34;
	height=&#34;486&#34;
	srcset=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-2_hu_706a70bd65b948d2.png 480w, https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-2_hu_8120918c8f57f88d.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;108&#34;
		data-flex-basis=&#34;260px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;This time I&amp;rsquo;ve included GB Camera emulation again. In GiiBiiAdvance
0.1.0 was removed (GiiBii had it). This time I&amp;rsquo;ve documented it all, and
I&amp;rsquo;m planning on doing some reverse engineering on the real hardware
(I&amp;rsquo;ve bought a few cartridges just in case I break one). For now, I&amp;rsquo;ve
only used the GB Camera software to see how it works, and I&amp;rsquo;ve managed
to emulate almost everything (contrast, dithering and brightness). It is
quite complicated to do emulate brightness because it depends on the
webcam and on the GB Camera software, so it changes weirdly sometimes.
The documentation is in &amp;ldquo;/docs/&amp;rdquo; folder in GitHub.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-3.png&#34;
	width=&#34;256&#34;
	height=&#34;224&#34;
	srcset=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-3_hu_e494972a9e586432.png 480w, https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-3_hu_4c762840dbf7707d.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;114&#34;
		data-flex-basis=&#34;274px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Of course, there is a debugger. I&amp;rsquo;ve improved it since 0.1.0, and now it
allows to dump any image that it displays. There are more changes, see
the changelog in the source code if you are interested.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-4.png&#34;
	width=&#34;1453&#34;
	height=&#34;1098&#34;
	srcset=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-4_hu_ce8573ee75a8f0e3.png 480w, https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-4_hu_2549afc0d4712e1f.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;132&#34;
		data-flex-basis=&#34;317px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-5.png&#34;
	width=&#34;1218&#34;
	height=&#34;1056&#34;
	srcset=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-5_hu_994ab3bb0188a017.png 480w, https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-5_hu_8d31a8c2e8de0543.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;115&#34;
		data-flex-basis=&#34;276px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-6.png&#34;
	width=&#34;1056&#34;
	height=&#34;1420&#34;
	srcset=&#34;https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-6_hu_3ff4bec53478614c.png 480w, https://skylyrac.net/p/2014-04-04-giibiiadvance-0-2-0/giibiiadvance-v0-2-0-screen-6_hu_9dcd6599a03c12f8.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;74&#34;
		data-flex-basis=&#34;178px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;The binaries are here. There are binaries for Windows and Linux
Mint/Ubuntu, with and without webcam support:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/giibiiadvance/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac/giibiiadvance/releases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I hope you like it!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updated links from GitHub to Codeberg.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>32x8 Yellow LED Matrix</title>
        <link>https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/</link>
        <pubDate>Sat, 30 Mar 2013 00:53:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-1.jpg" alt="Featured image of post 32x8 Yellow LED Matrix" /&gt;&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been messing around with electronics lately (after all, that&amp;rsquo;s what I&amp;rsquo;m
studying :P), and this is the result! A 32x8 LED Matrix controlled by a
PIC18F2550. You can click in the pictures for full size! At the end of the post
there is a video of the screen running.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-1.jpg&#34;
	width=&#34;1000&#34;
	height=&#34;750&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-1_hu_63c09c648d00d56.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-1_hu_d11c8a1b358fb01d.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;It can show any image you want, and the microcontroller can hold more than 900
of them! You can set individual times for displaying each frame. Apart from
that, you can connect it to a UART port and stream data directly from the
computer. The UART connector is the 2x13 pin connector, but only 3 pin are
soldered. I did it this way because it is easier to connect it to the Raspberry
Pi without making errors.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve used the 18F2550 because I had a few of them at home, and I want to make a
driver for streaming using USB instead of UART. It is running at 20MHz from an
external crystal oscillator.&lt;/p&gt;
&lt;p&gt;Connected to the Raspberry Pi and power:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-2.jpg&#34;
	width=&#34;750&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-2_hu_57567b0e84c09195.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-2_hu_f646685a81a7d049.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;319px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Now, some pictures of the boards. First, the simple (but a REAL pain to
solder, it took about 6 hours) 32x8 &lt;strong&gt;LED board&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-3.jpg&#34;
	width=&#34;750&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-3_hu_6e94c04907853776.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-3_hu_ee8f91f427675fc0.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;319px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-4.jpg&#34;
	width=&#34;750&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-4_hu_2b2dacd62246e898.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-4_hu_b4062e69899f39cf.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;319px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;A detail of the soldering:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-5.jpg&#34;
	width=&#34;1000&#34;
	height=&#34;750&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-5_hu_695de0a3f2e3289.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-5_hu_cd5c21b16e86d301.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Now, the &lt;strong&gt;expansion board&lt;/strong&gt;. It basically holds some 74HCT164 (SIPO registers),
some transistors and resistors.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-6.jpg&#34;
	width=&#34;750&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-6_hu_8bb5c40294ccc77a.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-6_hu_b36a5651a795d88e.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;319px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-7.jpg&#34;
	width=&#34;750&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-7_hu_26129789343f97b9.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-7_hu_648bbc2b9ec5b5f.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;319px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Last, but not least, the &lt;strong&gt;control board&lt;/strong&gt;, which holds the microcontroller (a
PIC18F2550), a decoder, and a buffer. The decoder is 4:16, it should be 3:8 but
I didn&amp;rsquo;t have one of them at home (well, I had one but not negative logic). The
buffer is actually a quad 2-input OR gate chip, I didn&amp;rsquo;t have one buffer either,
and I needed it to convert voltage levels for the Raspberry Pi. Anyway, using
the 4:16 decoder was not a terrible idea because I soldered the 4 inputs to the
PIC and I can use the most significant one to turn off and on the screen (I
could have used the enable pin, but hey&amp;hellip;). The button is just the reset
button, and the 4 DIP switches are connected to the PIC, but only the left one
is used for now (for switching between UART streaming and automatic mode). The
USB is not used for now.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-8.jpg&#34;
	width=&#34;750&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-8_hu_4fd8d0833367b7c3.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-8_hu_74ff05593b55aaaa.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;319px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-9.jpg&#34;
	width=&#34;750&#34;
	height=&#34;563&#34;
	srcset=&#34;https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-9_hu_3c6c2a98642e0bf8.jpg 480w, https://skylyrac.net/p/2013-03-30-32x8-yellow-led-matrix/led-screen-9_hu_7f286dbb61a4e8a7.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;319px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;The yellow LED is just a power indicator, the red and green ones are TX/RX
indicators, and the other red led is unused for now (it lights if there is a USB
cable connected at power up). And yeah, the PIC is in a socket in another
socket, just to make it really easy to remove it from the board. :P&lt;/p&gt;
&lt;p&gt;And here it is, a &lt;a class=&#34;link&#34; href=&#34;http://www.youtube.com/watch?v=-Fc5kiTPeHQ&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;video of the display running&lt;/a&gt;.
I can&amp;rsquo;t embed the video here.&lt;/p&gt;
&lt;p&gt;The software at the PC side is shown in the video, but it is basically a 32x8
matrix you can edit with the mouse and keyboard. You can also type a text and
the program will convert it to an animation! There are some things missing, like
error checking and sending again the data if the microcontroler says the packet
is corrupted. It is coded in C with SDL, using software rendering because the
Raspberry Pi version of SDL doesn&amp;rsquo;t have OpenGL support.&lt;/p&gt;
&lt;p&gt;If someone asks I could make schematics and upload them, and the code (in
assembly) for the PIC too, but there are a lot of tutorials for making LED
Matrix screens so I think it&amp;rsquo;s not necessary.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Root Locus 0.3</title>
        <link>https://skylyrac.net/p/2012-09-30-root-locus-0-3/</link>
        <pubDate>Sun, 30 Sep 2012 13:21:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2012-09-30-root-locus-0-3/</guid>
        <description>&lt;p&gt;Well, I should have put this here a few months ago, but I&amp;rsquo;ve been lazy to do so.&lt;/p&gt;
&lt;p&gt;Anyway, here is Root Locus 0.3. It now supports discrete systems, and it lets
you set a value for &amp;lsquo;k&amp;rsquo; (the one of the regulator) manually. You can also ask it
for the position of the poles in the current position. Everything is in the
manual.&lt;/p&gt;
&lt;p&gt;Link to hpcalc: &lt;a class=&#34;link&#34; href=&#34;http://www.hpcalc.org/details.php?id=7354&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.hpcalc.org/details.php?id=7354&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/rlocus_0_3.zip&#34; &gt;Download (binary + source)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2018-03-23)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This project is now hosted in &lt;a class=&#34;link&#34; href=&#34;https://github.com/AntonioND/rlocus&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-01-14)&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;This project is now hosted in &lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac/rlocus&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Codeberg&lt;/a&gt;.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Root Locus 0.2</title>
        <link>https://skylyrac.net/p/2012-02-04-root-locus-0-2/</link>
        <pubDate>Sat, 04 Feb 2012 14:28:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2012-02-04-root-locus-0-2/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2012-02-04-root-locus-0-2/root-locus-v0-2.png" alt="Featured image of post Root Locus 0.2" /&gt;&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;This is a program I&amp;rsquo;ve been coding for university. It is a library for the
HP50g. This program draws the root locus of a given transfer function and lets
you add a regulator, as well as change the proportional value of the regulator
and see the new position for the poles of the system for that value.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2012-02-04-root-locus-0-2/root-locus-v0-2.png&#34;
	width=&#34;524&#34;
	height=&#34;320&#34;
	srcset=&#34;https://skylyrac.net/p/2012-02-04-root-locus-0-2/root-locus-v0-2_hu_534a913e4036f3fe.png 480w, https://skylyrac.net/p/2012-02-04-root-locus-0-2/root-locus-v0-2_hu_9c0c6e50a5e1501a.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;163&#34;
		data-flex-basis=&#34;393px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve sent it to &lt;a class=&#34;link&#34; href=&#34;http://www.hpcalc.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;www.hpcalc.org&lt;/a&gt;, too. There are a lot of
great programs there. Anyway, the download link is here:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/rlocus_0_2.zip&#34; &gt;Download (Binary + Source)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are instructions on how to install and use it, they should be clear enough
for anybody. The source code is included (HP-GCC 2.0 and HP files for packaging
the library).&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Nitro Engine v0.6.1</title>
        <link>https://skylyrac.net/p/2011-09-01-nitro-engine-v0-6-1/</link>
        <pubDate>Thu, 01 Sep 2011 16:02:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2011-09-01-nitro-engine-v0-6-1/</guid>
        <description>&lt;p&gt;Well&amp;hellip; I just looked at the code this morning and saw that the code looked
horrible&amp;hellip; So I just reorganised it a bit (included the code of examples),
added a few &amp;ldquo;static&amp;rdquo; keywords and fixed a few warnings related to new versions
of libnds and devkitARM. Nothing else, though. Everything worked fine, so I
didn&amp;rsquo;t have to do anything else&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/old-site/nitroengine.html&#34; &gt;Link to web with the download information and those things.&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GiiBiiAdvance v0.1.0</title>
        <link>https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/</link>
        <pubDate>Fri, 26 Aug 2011 17:14:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-gba-vram.png" alt="Featured image of post GiiBiiAdvance v0.1.0" /&gt;&lt;p&gt;Special &lt;a class=&#34;link&#34; href=&#34;http://www.scenebeta.com/noticia/scenery-beta-2011-international-homebrew-showcase&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Scenery Beta 2011&lt;/a&gt;
edition.&lt;/p&gt;
&lt;p&gt;This is what I&amp;rsquo;ve been working on since last summer, and I think it is a quite
good program right now. It is just another GBA emulator, just like
&lt;a class=&#34;link&#34; href=&#34;http://vba.ngemu.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VisualBoyAdvance&lt;/a&gt;, and it emulates the same: GB, GBC,
SGB and GBA.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve used the GB, GBC and SGB emulation code from GiiBii, so GiiBiiAdvance has
the same compatibility (a bit more, I&amp;rsquo;ve changed a bit of SGB emulation code).
GBA emulation is, on the other hand, not really high. I mean, lots of ROMs work,
but some of them just show a black screen, or hang when you try to start the
game from the menu&amp;hellip; Everything of GBA is emulated (except the serial port),
but there are bugs I can&amp;rsquo;t find, I&amp;rsquo;ll work on it until I get a better
compatibility. Of course, it emulates all save chips, but some saves aren&amp;rsquo;t
compatible with other emulators. It will try to guess the save type if it can&amp;rsquo;t
detect it from the ROM. It lets you take screenshots, and GB Printer output is
saved as a png image. GB Camera is not emulated yet, though, so if you want to
play with that ROM, use GiiBii.&lt;/p&gt;
&lt;p&gt;There is also a quite good debugger, with a disassembler, memory viewer, I/O
ports viewer, tile viewer, map viewer, palette viewer and sprite viewer. They
are different in GBx and GBA mode. If you are playing a SGB game, there is also
a SGB things viewer. I have to make it easy to dump/save things, right now it
only lets you watch. So&amp;hellip; here are some screens:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GBA mode&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-gba.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-gba_hu_ea54ee9a9053c859.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-gba_hu_b951aa94705cc602.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-gba-dis.png&#34; &gt;GBA Disassembler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-gba-mem.png&#34; &gt;GBA Memory viewer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-gba-io.png&#34; &gt;GBA I/O viewer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-gba-vram.png&#34; &gt;GBA VRAM viewer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;GBC mode&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-gbc.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-gbc_hu_6456a07a0ce9ee31.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-gbc_hu_f51072e342006f6c.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-gbc-dis.png&#34; &gt;GBC Disassembler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-gbc-mem.png&#34; &gt;GBC Memory viewer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-gbc-io.png&#34; &gt;GBC I/O viewer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-gbc-vram.png&#34; &gt;GBC VRAM viewer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;SGB mode&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-sgb.png&#34;
	width=&#34;256&#34;
	height=&#34;224&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-sgb_hu_b0a0bfa0aaacdd1d.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-sgb_hu_c8c763625c053a33.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;114&#34;
		data-flex-basis=&#34;274px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;./giibiiadvance-v0-1-0-sgb-view.png&#34; &gt;SGB viewer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the &lt;strong&gt;downloads&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibiiadvance_010_bin.rar&#34; &gt;Binary (windows only)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibiiadvance_010_src.rar&#34; &gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So&amp;hellip; that&amp;rsquo;s it. I hope this program is useful for somebody. About the splash
screen&amp;hellip; You can close it by clicking it, or just waiting 4 seconds. It is
disabled in the source code.&lt;/p&gt;
&lt;p&gt;Oh, the last thing. If you want real SGB emulation, try &lt;a class=&#34;link&#34; href=&#34;http://byuu.org/bsnes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;bsnes&lt;/a&gt;.
It&amp;rsquo;s an impressive SNES emulator, and lets you load and use a Game Boy ROM with
Super Game Boy ROM.&lt;/p&gt;
&lt;p&gt;A few more screenshots in GBA mode:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-1.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-1_hu_bf9076a3f76a3f7c.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-1_hu_4e9c212cc0f6dab5.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-2.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-2_hu_e8c7d0ef178b7774.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-2_hu_2188eddb8482ba4f.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-3.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-3_hu_92c480f64be431ed.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-3_hu_47b46f32cedc40d7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-4.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-4_hu_18e74b330d85893d.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-4_hu_b2e66f825e70852d.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-5.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-5_hu_c3301e31bc83ce4f.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-5_hu_175804616ff079b3.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-6.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-6_hu_1683a372b13d711d.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-6_hu_b1d24725f6930f15.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-7.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-7_hu_e7127d965b138ac7.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-7_hu_b37332c04e1881b6.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-8.png&#34;
	width=&#34;240&#34;
	height=&#34;160&#34;
	srcset=&#34;https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-8_hu_5450e90db304eaa0.png 480w, https://skylyrac.net/p/2011-08-26-giibiiadvance-v0-1-0/giibiiadvance-v0-1-0-screen-8_hu_96d0f5217e9b24e3.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;150&#34;
		data-flex-basis=&#34;360px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Bye!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GiiBii v0.3</title>
        <link>https://skylyrac.net/p/2010-08-27-giibii-v0-3/</link>
        <pubDate>Fri, 27 Aug 2010 16:55:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2010-08-27-giibii-v0-3/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-1.png" alt="Featured image of post GiiBii v0.3" /&gt;&lt;p&gt;Special &lt;a class=&#34;link&#34; href=&#34;http://www.scenebeta.com/noticia/scenery-beta-2010-international-homebrew-showcase-rules&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Scenery Beta 2010&lt;/a&gt;
version!&lt;/p&gt;
&lt;p&gt;The most important change is that it now uses OpenGL instead of drawing directly
to the framebuffer, which makes it work a bit faster. I&amp;rsquo;ve also allowed to use
3x zoom because the screen size is no longer a problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dissasembler fixes.&lt;/li&gt;
&lt;li&gt;Debugger screen now gets focus when reaching a breakpoint.&lt;/li&gt;
&lt;li&gt;Changed to OpenGL, allowed 3x zoom. Fullscreen mode is buggy, sometimes it
crashes when returning to windowed mode&amp;hellip; :S&lt;/li&gt;
&lt;li&gt;Rumble &amp;ldquo;emulated&amp;rdquo; (screen shakes a bit).&lt;/li&gt;
&lt;li&gt;MBC7 fixed (Kirby Tilt &amp;rsquo;n&amp;rsquo; Tumble).&lt;/li&gt;
&lt;li&gt;Mapper code optimized a bit.&lt;/li&gt;
&lt;li&gt;Stat bug emulated (Legend of Zerd, Road Rash now work in non-color Game Boy
modes).&lt;/li&gt;
&lt;li&gt;Game Boy Pocket screen is now white, you can only change the color of the
normal Game Boy screen.&lt;/li&gt;
&lt;li&gt;Sound emulation code partially optimized. Also, it is more accurate now (and
it can save the sound output to a wav file, but the code is disabled this
version because it needs testing).&lt;/li&gt;
&lt;li&gt;CPU fixes: Zero flag for opcodes &lt;code&gt;RRA&lt;/code&gt; / &lt;code&gt;RR A&lt;/code&gt;, &lt;code&gt;RCLA&lt;/code&gt; / &lt;code&gt;RCL A&lt;/code&gt;, etc&amp;hellip;&lt;/li&gt;
&lt;li&gt;Added a filter to make colors more &amp;ldquo;realistic&amp;rdquo;. You can enable it in the menu,
and you can also enable or disable the frame mix filter that comes with GiiBii
since first version.&lt;/li&gt;
&lt;li&gt;Discovered why Alleyway didn&amp;rsquo;t work: GB Printer was enabled.&lt;/li&gt;
&lt;li&gt;Fixed a bug in &lt;code&gt;ICON_EN&lt;/code&gt; SGB command that made graphics have serious glitches
in some games (DK2, DK3).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Downloads&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v03_bin_windows.rar&#34; &gt;Binaries (win32)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v03_bin_linux.rar&#34; &gt;Binaries (Linux)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You need SDL and GTK+ (and OpenCV for the GB Camera).&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v03_src.rar&#34; &gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Emulation may be more accurate if you put the GB boot roms in the &amp;ldquo;boot&amp;rdquo;
folder of the emulator (see the readme.txt). They aren&amp;rsquo;t included with the
download.&lt;/li&gt;
&lt;li&gt;You can load a ROM by grabbing it to the GiiBii exe file (or using
the command line &amp;ldquo;GiiBii myrom.gb&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;If you want free ROMs, go to &lt;a class=&#34;link&#34; href=&#34;http://www.pdroms.de/files/gameboy/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;PDRoms&lt;/a&gt;.
If you are looking for commercial games, I can&amp;rsquo;t help you.&lt;/li&gt;
&lt;li&gt;This emulator will be mixed someday with GiiBiiAdvance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Screenshots&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-1.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-1_hu_2184e91248680a54.png 480w, https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-1_hu_713ddd8bf74eb245.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-2.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-2_hu_800e271cacd2fc0c.png 480w, https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-2_hu_a53ce554c3f08089.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-3.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-3_hu_1d04000632143c95.png 480w, https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-3_hu_82c4c873f73b68cf.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-4.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-4_hu_13e5aed4d3a93049.png 480w, https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-4_hu_e8838617f7813436.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-5.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-5_hu_cd23e4fa448cd6dd.png 480w, https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-5_hu_b3db6bcba8df2554.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-6.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-6_hu_a68f9dcdbca0226e.png 480w, https://skylyrac.net/p/2010-08-27-giibii-v0-3/giibii-v0-3-screen-6_hu_59237c50b6ddf4b7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GiiBiiAdvance - WIP</title>
        <link>https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/</link>
        <pubDate>Wed, 25 Aug 2010 13:06:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-debugger.png" alt="Featured image of post GiiBiiAdvance - WIP" /&gt;&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;Since GiiBii works really well for what I expected, I wanted to do a GBA
emulator. I&amp;rsquo;ve been working on it since July, and after 2 months of work, here
are some results:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-screenshot-1.png&#34;
	width=&#34;246&#34;
	height=&#34;212&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-screenshot-1_hu_ee2b44427a62bb8d.png 480w, https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-screenshot-1_hu_7a836cdccd568050.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;Kirby - Nightmare in Dream Land&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;116&#34;
		data-flex-basis=&#34;278px&#34;
	
&gt;
&lt;img src=&#34;https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-screenshot-2.png&#34;
	width=&#34;246&#34;
	height=&#34;212&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-screenshot-2_hu_775c2e613261a6b7.png 480w, https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-screenshot-2_hu_35c4f0928500f422.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;Need For Speed - Underground 2&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;116&#34;
		data-flex-basis=&#34;278px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Kirby - Nightmare in Dream Land&amp;rdquo; and &amp;ldquo;Need For Speed - Underground 2&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Obviously, there is still a lot to do, most games are unplayable (in fact, NFS
runs very slowly, there is a problem with CPU timing, I guess), have graphic
glitches (where is the needle of the speedometer? :P) or just can&amp;rsquo;t pass from
the initial splash screens (if they can show them&amp;hellip;).&lt;/p&gt;
&lt;p&gt;What is done:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU emulation (ARM and THUMB), but it is still buggy.&lt;/li&gt;
&lt;li&gt;DMA channels (except special modes).&lt;/li&gt;
&lt;li&gt;All BG modes and regular (non-affine) sprites are emulated. No special effects
or window effects, though.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VBL&lt;/code&gt;, &lt;code&gt;HBL&lt;/code&gt;, &lt;code&gt;VCOUNT&lt;/code&gt;, &lt;code&gt;DMA&lt;/code&gt; and &lt;code&gt;KEYPAD&lt;/code&gt; interrupt requests.&lt;/li&gt;
&lt;li&gt;Disassembler, I/O register viewer (both aren&amp;rsquo;t finished) and memory viewer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A capture of the debugger:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-debugger.png&#34;
	width=&#34;1024&#34;
	height=&#34;768&#34;
	srcset=&#34;https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-debugger_hu_43b4bb3a85610d6b.png 480w, https://skylyrac.net/p/2010-08-25-giibiiadvance-wip/giibiiadvance-wip-debugger_hu_b47e98d3087ba41.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Yeah, that&amp;rsquo;s a Tonc demo.&lt;/p&gt;
&lt;p&gt;PS: A new version of GiiBii is coming in a few days :P.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GiiBii v0.2</title>
        <link>https://skylyrac.net/p/2010-02-02-giibii-v0-2/</link>
        <pubDate>Tue, 02 Feb 2010 23:06:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2010-02-02-giibii-v0-2/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2010-02-02-giibii-v0-2/giibii-v0-2-printer.png" alt="Featured image of post GiiBii v0.2" /&gt;&lt;p&gt;New version! This time, GiiBii comes with an interesting new feature&amp;hellip; It can
emulate the GB Camera with camera features! I&amp;rsquo;ll explain more about this later,
before that:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New mappers supported: MMM01 (Taito Variety Pack works, Momotarou Collection 2
doesn&amp;rsquo;t&amp;hellip;), MBC7 (controls need some improvements&amp;hellip;).&lt;/li&gt;
&lt;li&gt;You can set the screen size to 1x or 2x now.&lt;/li&gt;
&lt;li&gt;You can reset the ROM instead of having to exit it and reload the ROM.&lt;/li&gt;
&lt;li&gt;Now the console shows more information when loading a ROM (like the licensee
name).&lt;/li&gt;
&lt;li&gt;You can set customized controls for 4 players (yeah, SGB multiplayer works
again ^^).&lt;/li&gt;
&lt;li&gt;You can change volume or enable/disable each sound channel.&lt;/li&gt;
&lt;li&gt;Stop mode emulated correctly (but I&amp;rsquo;ve never seen any game using it, I&amp;rsquo;ve
coded it just by testing on my GBC).&lt;/li&gt;
&lt;li&gt;Added breakpoint support.&lt;/li&gt;
&lt;li&gt;Debugger font size can be changed (take a look at the ini file).&lt;/li&gt;
&lt;li&gt;A few little bugfixes and improvements&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Downloads&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v02_bin.rar&#34; &gt;Binaries (win32)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Binaries (Linux) &amp;ndash; coming soon&amp;hellip; :)&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v02_src.rar&#34; &gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Very messy, camera functions in &amp;ldquo;memory.c&amp;rdquo; (nothing special, though).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Game Boy Camera&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;This version of GiiBii can emulate camera features of GB Camera just by using a
webcam. For getting the pictures from it, GiiBii uses OpenCV, which is
cross-platform, just like SDL and GTK+. GiiBii will try to use as much
information as possible from the webcam, and scale it down to the GB size. This
is just the first version with camera support, you can expect some improvements
in next versions. For example, brightness is emulated very badly&amp;hellip; but hey, it
&amp;ldquo;works&amp;rdquo;. On the other hand, contrast doesn&amp;rsquo;t work&amp;hellip; What I&amp;rsquo;m trying to say is
that you will have to wait if you want a better support. Just remember that this
emulator isn&amp;rsquo;t as fast as it could be, so don&amp;rsquo;t expect it running as well as the
other emulators you&amp;rsquo;ve tried. Anyway, take a look at what it can do now :) :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2010-02-02-giibii-v0-2/giibii-v0-2-printer.png&#34;
	width=&#34;160&#34;
	height=&#34;144&#34;
	srcset=&#34;https://skylyrac.net/p/2010-02-02-giibii-v0-2/giibii-v0-2-printer_hu_5e95ede5c93826bd.png 480w, https://skylyrac.net/p/2010-02-02-giibii-v0-2/giibii-v0-2-printer_hu_c81ddd72b6d967f7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;111&#34;
		data-flex-basis=&#34;266px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Try taking a picture and &amp;ldquo;printing&amp;rdquo; it using GB Printer (which is emulated). :)&lt;/p&gt;
&lt;p&gt;Just a note: It may freeze a second or so when loading the GB Camera ROM
(because of the webcam being initialized). If you want to enable the webcam
window, enable debug messages and it will load when opening the GB Camera ROM.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GB Camera emulated with a webcam!</title>
        <link>https://skylyrac.net/p/2010-02-02-gb-camera-emulated-webcam/</link>
        <pubDate>Tue, 02 Feb 2010 15:29:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2010-02-02-gb-camera-emulated-webcam/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2010-02-02-gb-camera-emulated-webcam/gb-camera-emulated-webcam.png" alt="Featured image of post GB Camera emulated with a webcam!" /&gt;&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2010-02-02-gb-camera-emulated-webcam/gb-camera-emulated-webcam.png&#34;
	width=&#34;1024&#34;
	height=&#34;768&#34;
	srcset=&#34;https://skylyrac.net/p/2010-02-02-gb-camera-emulated-webcam/gb-camera-emulated-webcam_hu_597af8fa2d3c3d8a.png 480w, https://skylyrac.net/p/2010-02-02-gb-camera-emulated-webcam/gb-camera-emulated-webcam_hu_fdc41fd38e0f1f0e.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Uhmmm&amp;hellip; yeah&amp;hellip; ^_^&lt;/p&gt;
&lt;p&gt;PS: I&amp;rsquo;m using OpenCV for getting the webcam data.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GBT Player v1.1</title>
        <link>https://skylyrac.net/p/2009-10-24-gbt-player-v1-0/</link>
        <pubDate>Sat, 24 Oct 2009 16:06:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2009-10-24-gbt-player-v1-0/</guid>
        <description>&lt;p&gt;Hello again!&lt;/p&gt;
&lt;p&gt;This time I&amp;rsquo;m going to show you a music player&amp;hellip; for Game Boy. :P It&amp;rsquo;s very
easy to use, and easy to compose music for it. I&amp;rsquo;ve included source code (100%
asm) and templates for &lt;a class=&#34;link&#34; href=&#34;https://github.com/JustinLloyd/RGBDS-Gameboy-Development-System&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RGBDS&lt;/a&gt;
and &lt;a class=&#34;link&#34; href=&#34;http://gbdk.sourceforge.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBDK&lt;/a&gt;. You have to compose the music in a
tracker in the PC using a custom mod file included in the download. Available
effects and other instructions to modify it are in a text file in the download.
Then, you convert it using a special tool which will export the data to a GBDK C
file or a RGBDS asm file. Included templates can be compiled by double clicking
the bat files, so you can use them for testing your songs as you compose them
(I&amp;rsquo;d use the RGBDS one). For any other information, look at the readme, or ask
me. There is an example there, the rest should be self-explanatory.&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/gbt_player_v1_0.rar&#34; &gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PS: Is there anybody who still codes for GB? :P&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Some incorrect definitions changed:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/gbt_player_v1_1.7z&#34; &gt;Download version 1.1&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Pascal Pong v0.1</title>
        <link>https://skylyrac.net/p/2009-10-24-pascal-pong-v0-1/</link>
        <pubDate>Sat, 24 Oct 2009 01:31:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2009-10-24-pascal-pong-v0-1/</guid>
        <description>&lt;p&gt;Well&amp;hellip; This is what happens when I&amp;rsquo;m bored and I feel a bit guilty because I
haven&amp;rsquo;t practised anything with pascal (they make us code with Turbo Pascal in
university)&amp;hellip; I don&amp;rsquo;t know exactly why I&amp;rsquo;ve put v0.1 as there won&amp;rsquo;t probably be
more updates&amp;hellip; :P Anyway, download links here, source + win32 binary:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/pascal_pong.rar&#34; &gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And a screenshot&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2009-10-24-pascal-pong-v0-1/pascal-pong.png&#34;
	width=&#34;652&#34;
	height=&#34;638&#34;
	srcset=&#34;https://skylyrac.net/p/2009-10-24-pascal-pong-v0-1/pascal-pong_hu_6342b7875d9a04b0.png 480w, https://skylyrac.net/p/2009-10-24-pascal-pong-v0-1/pascal-pong_hu_db4a894fb4e6d6dd.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;102&#34;
		data-flex-basis=&#34;245px&#34;
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GiiBii v0.1</title>
        <link>https://skylyrac.net/p/2009-10-02-giibii-v0-1/</link>
        <pubDate>Fri, 02 Oct 2009 12:53:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2009-10-02-giibii-v0-1/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2009-10-02-giibii-v0-1/giibii-v0-1-2.jpg" alt="Featured image of post GiiBii v0.1" /&gt;&lt;p&gt;Well, it took me some days more to finish this because of some (sound related)
bugs I couldn&amp;rsquo;t fix, but here it is! GiiBii v0.1, first version of GiiBii for
PC. I hope you like it. I think this is the first &amp;ldquo;official&amp;rdquo; release of an
emulator that supports the GBC boot ROM (not included in the downloads). :)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2009-10-02-giibii-v0-1/giibii-v0-1-2.jpg&#34;
	width=&#34;1024&#34;
	height=&#34;768&#34;
	srcset=&#34;https://skylyrac.net/p/2009-10-02-giibii-v0-1/giibii-v0-1-2_hu_afe4c88bb55960cf.jpg 480w, https://skylyrac.net/p/2009-10-02-giibii-v0-1/giibii-v0-1-2_hu_cda19d99fe687131.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Supports MBC1, MBC2, MBC3 (RTC emulated), MBC5, HuC-1.&lt;/li&gt;
&lt;li&gt;Sound channels emulated correctly (you can hear &amp;ldquo;Pikachu!&amp;rdquo; in Pokemon Yellow,
for example).&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Turbo&amp;rdquo; mode. Not extremely fast, though&amp;hellip; This emulator is not meant to be
fast, but to be accurate.&lt;/li&gt;
&lt;li&gt;Supports boot ROMs (bios). At the moment of writing this only DMG, SGB and CGB
have been dumped, but GiiBii is prepared for the other ones as well (they may
not work, as they haven&amp;rsquo;t been tested).&lt;/li&gt;
&lt;li&gt;It can generate screenshots in PNG format.&lt;/li&gt;
&lt;li&gt;GB Printer emulated, images are saved into the screenshots folder in PNG
format, too.&lt;/li&gt;
&lt;li&gt;Allows changing the screen palette in GB mode.&lt;/li&gt;
&lt;li&gt;Super Game Boy is emulated, though some commands aren&amp;rsquo;t coded (sound, default
palettes&amp;hellip;).&lt;/li&gt;
&lt;li&gt;Debugger and VRAM viewer (debugger is not complete yet).&lt;/li&gt;
&lt;li&gt;Uses SDL and GTK+, cross platform libraries, so it should be very easy to
port to Linux, for example (I&amp;rsquo;ll check it and upload a binary when done).&lt;/li&gt;
&lt;li&gt;GiiBii is open source, it is licensed under the GPL v3 so you can modify it
but you have to make modifications open source too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And finally, the &lt;strong&gt;downloads&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v01_bin.rar&#34; &gt;Binaries&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v01_src.rar&#34; &gt;Source&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GiiBii... now on PC!</title>
        <link>https://skylyrac.net/p/2009-09-19-giibii-now-on-pc/</link>
        <pubDate>Sat, 19 Sep 2009 10:42:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2009-09-19-giibii-now-on-pc/</guid>
        <description>&lt;img src="https://skylyrac.net/p/2009-09-19-giibii-now-on-pc/giibii-v0-1.png" alt="Featured image of post GiiBii... now on PC!" /&gt;&lt;p&gt;Well, this is the first &amp;ldquo;real&amp;rdquo; post. :P&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been working on a port of GiiBii (my Game Boy emulator) to PC for about 3
weeks. It has been a bit difficult, as I used libraries that are only available
in Wii (libogc, asndlib&amp;hellip;), and I wanted to make the port using only
cross-platform libraries (as I want to make Linux binaries).&lt;/p&gt;
&lt;p&gt;The first thing I have to decide was the graphics library I could use in PC. I
decided that SDL was a good idea because it also gives a low-level sound API,
just what I need to improve the audio system of my emulator (yeah, the Wii
version uses a really bad system and there are glitches many times). When I
managed to get it to compile, I started porting the emulator. I deleted a lot of
code and, after commenting a lot of parts like sound, input, Super Game Boy
emulation, I managed to get it to compile. Then I started to fix that parts.
When I finished with the input and the SGB ones, I decided it was time to begin
with the GUI.&lt;/p&gt;
&lt;p&gt;I looked for a library to make it. I found out that GTK+ was a good one, and I
started to put together GTK+ and SDL. When it was ready, I started to code the
GUI. GTK+ is a bit difficult at the beginning, but when you get used to it, you
can see that it&amp;rsquo;s really useful. After a lot of hours of work, I finally made a
little menu with almost all options that you can see in the Wii binary and
rewrote the debugger.&lt;/p&gt;
&lt;p&gt;This is the result:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://skylyrac.net/p/2009-09-19-giibii-now-on-pc/giibii-v0-1.png&#34;
	width=&#34;1024&#34;
	height=&#34;768&#34;
	srcset=&#34;https://skylyrac.net/p/2009-09-19-giibii-now-on-pc/giibii-v0-1_hu_b2ee87a1d5a69154.png 480w, https://skylyrac.net/p/2009-09-19-giibii-now-on-pc/giibii-v0-1_hu_9e7e2ee052523043.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;133&#34;
		data-flex-basis=&#34;320px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;Cool, isn&amp;rsquo;t it? :)&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m rewriting the sound emulation part at the moment. I think that in a week or
so I will have finished it (and some parts of the menu) and I will release a
beta.&lt;/p&gt;
&lt;p&gt;Bye!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Welcome!</title>
        <link>https://skylyrac.net/p/2009-09-19-welcome/</link>
        <pubDate>Sat, 19 Sep 2009 01:15:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/p/2009-09-19-welcome/</guid>
        <description>&lt;p&gt;Hello everybody!&lt;/p&gt;
&lt;p&gt;This is my new blog. I think it&amp;rsquo;s time to create one, so that I can say when
update one of my projects, or just I&amp;rsquo;ve done something I consider interesting to
say. :) I&amp;rsquo;m not quite good at writing, and my English isn&amp;rsquo;t great, either, so
you can expect a lot of mistakes in my writing. Just let me know where I made
any mistake and I&amp;rsquo;ll correct it.&lt;/p&gt;
&lt;p&gt;By the way, this is &lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/old-site/index.html&#34; &gt;my other webpage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks to Dovoto for the hosting of both this blog and the other webpage! :D&lt;/p&gt;
&lt;p&gt;Now, time to go back to coding&amp;hellip;&lt;/p&gt;
&lt;p&gt;Bye!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>About me</title>
        <link>https://skylyrac.net/about-me/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/about-me/</guid>
        <description>&lt;p&gt;I&amp;rsquo;m &lt;strong&gt;Antonio Niño Díaz&lt;/strong&gt;, and this is a short story of my hacking life.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m Spanish, born in a city near Madrid. I studied Industrial Engineering in
Madrid, and specialized in Electronics and Control. After getting my degree I
got a job at Arm in Cambridge, UK, where I&amp;rsquo;ve lived since January 2016.&lt;/p&gt;
&lt;p&gt;Most of what I know about programming is self-taught. I started trying a few
simple things in BASIC on my father&amp;rsquo;s Amstrad CPC. I eventually came across Game
Maker and started to program for PC an to understand how games are made, what
objects are, that kind of things.&lt;/p&gt;
&lt;p&gt;At some point, when I was 15, I discovered that I could also write my own
programs for the Nintendo DS. That&amp;rsquo;s when I started to learn &lt;strong&gt;C&lt;/strong&gt;. Then I
realized everything that it could do, and the fact that it can be used to
develop for pretty much any device you can think of. It has been my favourite
programming language ever since.&lt;/p&gt;
&lt;p&gt;I also discovered microcontrollers thanks to the Wii hacking scene, and starting
to program a bit in assembly. I find it amazing that I can control things in the
real world by just programming a small chip. I&amp;rsquo;ve played quite a bit with PIC
microcontrollers.&lt;/p&gt;
&lt;p&gt;I eventually moved to PC and wrote GiiBiiAdvance, my GBC and GBA emulator. And
then, as I knew the instruction set of the GBC, I decided to start developing
things in assembly for the GBC.&lt;/p&gt;
&lt;p&gt;Something else I love are FPGAs. I learned about them at university, and I had
to buy one to play with at home. I don&amp;rsquo;t use it nearly as much as I&amp;rsquo;d like,
though, but it&amp;rsquo;s one of the things I&amp;rsquo;m most interested in at the moment.&lt;/p&gt;
&lt;p&gt;And this is the end, for now. Just take a look at my projects in this website,
and know that I&amp;rsquo;m always available to answer questions about them!&lt;/p&gt;
&lt;h2 id=&#34;contact-me&#34;&gt;Contact me
&lt;/h2&gt;&lt;p&gt;My &lt;strong&gt;email address&lt;/strong&gt; is antonio_nd at outlook or proton.me. You can also try
antonionidi at gmail, if the first one doesn&amp;rsquo;t work.&lt;/p&gt;
&lt;p&gt;You can see my projects in my &lt;strong&gt;Codeberg&lt;/strong&gt; account:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/SkyLyrac&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://codeberg.org/SkyLyrac&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I can also be found in some forums as &lt;strong&gt;AntonioND&lt;/strong&gt; or &lt;strong&gt;SkyLyrac&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://gbdev.gg8.se/forums/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBDev forums&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://forum.gbadev.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBADev (new forums)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, you can also find me in the &lt;a class=&#34;link&#34; href=&#34;https://gbdev.io/chat.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBDev&lt;/a&gt; and
&lt;a class=&#34;link&#34; href=&#34;https://gbadev.net&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GBADev&lt;/a&gt; discord servers (my username is skylyrac).&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Downloads</title>
        <link>https://skylyrac.net/downloads/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/downloads/</guid>
        <description>&lt;p&gt;&lt;strong&gt;GiiBiiAdvance v0.1.0&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibiiadvance_010_bin.rar&#34; &gt;Binaries (win32)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibiiadvance_010_src.rar&#34; &gt;Source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;GiiBii v0.3&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v03_bin_windows.rar&#34; &gt;Binaries (win32)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v03_bin_linux.rar&#34; &gt;Binaries (linux)&lt;/a&gt;
You need SDL and GTK+ (and OpenCV for the GB Camera).&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v03_src.rar&#34; &gt;Source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;GiiBii v0.2&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v02_bin.rar&#34; &gt;Binaries (windows)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v02_src.rar&#34; &gt;Source&lt;/a&gt; The camera functions are in
&amp;ldquo;memory.c&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;GiiBii v0.1&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v01_bin.rar&#34; &gt;Binaries (windows)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/giibii_pc_v01_src.rar&#34; &gt;Source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;GBT Player v1.0&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/gbt_player_v1_0.rar&#34; &gt;Source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Pascal Pong v0.1&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/pascal_pong.rar&#34; &gt;Source + Binaries (windows)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Root Locus 0.3&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://skylyrac.net/downloads/rlocus_0_3.zip&#34; &gt;Source + Binaries&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Search</title>
        <link>https://skylyrac.net/search/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://skylyrac.net/search/</guid>
        <description></description>
        </item>
        
    </channel>
</rss>
