Skip to content

Commit

Permalink
Deploying to gh-pages from @ 9341163 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
avivace committed Mar 1, 2024
1 parent 29a094f commit f23263a
Show file tree
Hide file tree
Showing 16 changed files with 83 additions and 75 deletions.
6 changes: 5 additions & 1 deletion ack.html
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,18 @@ <h1 class="menu-title">gbadoc</h1>
<div id="content" class="content">
<main>
<h1 id="acknowledgements"><a class="header" href="#acknowledgements">Acknowledgements</a></h1>
<ul>
<li><a href="https://github.com/velipso">Velipso</a>, author of the Bootleg Carts article.</li>
</ul>
<hr />
<p>The following are individuals who contributed info or corrections on the original CowBiteSpec document.</p>
<ul>
<li>Tom Happ</li>
<li>Agent Q (Wrote the original spec, version 1.0)</li>
<li>Uze (All of the sound register info comes directly from his Audio Advance site)</li>
<li>Martin Korth (Author no$gba of who has given me permission to consolidate additional info from his emulator's informative help documents with this one, most particularly serial registers, some BIOS functions, and undocumented registers.)</li>
<li>Forgotten (VBA Author. Many of the BIOS call descriptions come from his Visual Boy Advance FAQ.</li>
<li>gbcft (LOTS of info on interrupts, windowing, memory mirrors, the &quot;Unkown Registers&quot; section; helped me debug a lot of errors in the emulator, and offered many corrections, info, and suggestions).</li>
<li>gbcft (LOTS of info on interrupts, windowing, memory mirrors, the "Unkown Registers" section; helped me debug a lot of errors in the emulator, and offered many corrections, info, and suggestions).</li>
<li>Kay (Contributed memory port sizes and wait states, DMA cycle timings, info regarding the BIOS, and various advice, testing, and expertise regarding the GBA and older console systems)</li>
<li>Damian Yerrick (Contributed the WSCOUNT register)</li>
<li>Markus (Actually I asked him for help with LZSS. Also, his gfx2gba tool has proven extremely helpful in my non-CowBite projects.:)</li>
Expand Down
8 changes: 4 additions & 4 deletions audio/directsound.html
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,13 @@ <h2 id="dma-mode-direct-sound-example"><a class="header" href="#dma-mode-direct-
<li>Enable timer0 at Cpu frequency (clock divider=0)</li>
</ul>
<p>Sound should start immediately and will play past the sample if not stopped. You can use timer1 to count played samples and stop the sound. To do this, set timer 1 to cascade and enable irq for timer 1 and set its count to 0xffff-samples count. Your irq handler should stop the sound by disabling timer 0 and the dma channel(s).</p>
<pre><code class="language-C">#include &quot;gba.h&quot;
<pre><code class="language-C">#include "gba.h"

//the sample. its a pcm wave file converted to an elf file with objcopyroda.exe (devrs.com/gba)
extern const u32 _binary_lo1234_pcm_start[];

//the interrupt handler from crt0.s
void InterruptProcess(void) __attribute__((section(&quot;.iwram&quot;)));
void InterruptProcess(void) __attribute__((section(".iwram")));

void InterruptProcess(void) {
//sample finished!,stop Direct sound
Expand Down Expand Up @@ -308,12 +308,12 @@ <h2 id="interrupt-mode-direct-sound-example"><a class="header" href="#interrupt-
</ul>
</li>
</ul>
<pre><code class="language-C">#include &quot;gba.h&quot;
<pre><code class="language-C">#include "gba.h"

//the sample. its an pcm wave file converted to an elf file with objcopyroda.exe (devrs.com/gba)
extern const u32 _binary_lo1234_pcm_start[];
//the interrupt handler from crt0.s
void InterruptProcess(void) __attribute__((section(&quot;.iwram&quot;)));
void InterruptProcess(void) __attribute__((section(".iwram")));

int iNextSample = 0;
int SampleSize = 36712;
Expand Down
2 changes: 1 addition & 1 deletion audio/sound1.html
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ <h1 class="menu-title">gbadoc</h1>
<main>
<h1 id="sound-channel-1"><a class="header" href="#sound-channel-1">Sound Channel 1</a></h1>
<p>Sound channel 1 produces square waves with variable duty cycle, frequency sweep and envelope functions. It is often referred as a quadrangular wave pattern.</p>
<p>Frequency sweeps allows &quot;portamento&quot;-like effects where the frequency raises or decreases during playback. The amount of increase or decrease in frequency (or sweep shifts) and the rate at which it occurs (sweep time) is controllable. Frequency sweeps are controlled by REG_SOUND1CNT_L</p>
<p>Frequency sweeps allows "portamento"-like effects where the frequency raises or decreases during playback. The amount of increase or decrease in frequency (or sweep shifts) and the rate at which it occurs (sweep time) is controllable. Frequency sweeps are controlled by REG_SOUND1CNT_L</p>
<p>Sweep shifts are controlled by bits 0-2 and are calculated with the following formula:</p>
<p>\( T = T \pm \frac{T}{2^n} \) where T = Wave Period and n = Sweep Shifts</p>
<p>Sweep time (Ts) controls the delay between sweep shifts and is controlled by bits 4-6:</p>
Expand Down
2 changes: 1 addition & 1 deletion bios.html
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ <h3 id="0x12-lz77uncompvram"><a class="header" href="#0x12-lz77uncompvram"><code
Input: r0 = source address, r1 = dest address
</pre>
<p>Note: The LZ77 decompressors actually decompress LZSS, not LZ77, which is slightly different. You will have to look on the web to find the algorithm as it is beyond the scope of this document. The following assumes a general famliarity with LZSS.</p>
<p>On the GBA, the ring buffer or &quot;window&quot; is of size 4096, the minumim compressed length is 3 and the maximum compressed length is 18. Looking into a compressed buffer you will find the size of the uncompressed memory in bytes 2, 3, and 4 (I'm not sure what the first byte does, but it seems to always be set to &quot;01&quot;), followed by the coded data. This is divided up into sections consisting of an 8 bit key followed by a corresponding eight items of varying size. The upper bits in the key correspond to the items with lower addresses and vice versa. For each bit set in the key, the corresponding item will be 16 bits; the top bits four being the number of bytes to output, minus 3, and the bottom sixteen bits being the offset behind the current window position from which to output. For each bit which is not set, the corresponding item is an uncompressed byte and gets sent to the output.</p>
<p>On the GBA, the ring buffer or "window" is of size 4096, the minumim compressed length is 3 and the maximum compressed length is 18. Looking into a compressed buffer you will find the size of the uncompressed memory in bytes 2, 3, and 4 (I'm not sure what the first byte does, but it seems to always be set to "01"), followed by the coded data. This is divided up into sections consisting of an 8 bit key followed by a corresponding eight items of varying size. The upper bits in the key correspond to the items with lower addresses and vice versa. For each bit set in the key, the corresponding item will be 16 bits; the top bits four being the number of bytes to output, minus 3, and the bottom sixteen bits being the offset behind the current window position from which to output. For each bit which is not set, the corresponding item is an uncompressed byte and gets sent to the output.</p>
<p>Thanks to Markus for providing me with some source that helped me figure out all of this.</p>
<h3 id="0x13-huffuncomp"><a class="header" href="#0x13-huffuncomp"><code>0x13</code>: HuffUnComp</a></h3>
<p>Unpacks data compressed with Huffman and writes it 32-bits at a time.</p>
Expand Down
18 changes: 9 additions & 9 deletions bootleg-carts/introduction.html
Original file line number Diff line number Diff line change
Expand Up @@ -294,32 +294,32 @@ <h2 id="understanding-commands"><a class="header" href="#understanding-commands"
<p><img src="images/commands.png" alt="S29GL128N Commands" /></p>
<p>You can see that this information also exists in the FlashGBX source code, <a href="https://github.com/lesserkuma/FlashGBX/blob/9b44a9959bf9fd6bab5f1005ce1c757d2f456fa7/FlashGBX/config/fc_AGB_MSP55LV128M.txt">in the
config</a>:</p>
<pre><code class="language-javascript">&quot;reset&quot;:[
<pre><code class="language-javascript">"reset":[
[ 0, 0xF0 ]
],
&quot;read_identifier&quot;:[
"read_identifier":[
[ 0xAAA, 0xA9 ],
[ 0x555, 0x56 ],
[ 0xAAA, 0x90 ]
],
&quot;read_cfi&quot;:[
"read_cfi":[
[ 0xAA, 0x98 ]
],
...
</code></pre>
<p>Notice that the &quot;Auto-Select&quot; row doesn't exactly match the <code>&quot;read_identifier&quot;</code> information.</p>
<p>Notice that the "Auto-Select" row doesn't exactly match the <code>"read_identifier"</code> information.</p>
<p>Auto-Select starts with address <code>0xAAA</code>, data <code>0xAA</code>, but FlashGBX has address <code>0xAAA</code>, data
<code>0xA9</code> -- this is because D0/D1 are swapped (<code>10101010</code> -&gt; <code>10101001</code>)! <a href="#swapping-of-d0d1">See the section
above</a>.</p>
<p>So if we want to perform a reset on the chip, we just write <code>0xF0</code> to any address. Note that reset
doesn't <em>erase</em> the chip, it just resets any commands in progress.</p>
<pre><code class="language-c">// reset
*((u16 *)0x08000000) = 0xF0;
__asm(&quot;nop&quot;);
__asm("nop");
</code></pre>
<p>The forked goombacolor project from LesserKuma has example code, where <a href="https://github.com/lesserkuma/goombacolor/blob/f2bae8eb5087de14008250032c82cf5d294131cd/src/main.c#L585">you can see this
happen</a>:</p>
<pre><code class="language-c">#define _FLASH_WRITE(pa, pd) { *(((u16 *)AGB_ROM)+((pa)/2)) = pd; __asm(&quot;nop&quot;); }
<pre><code class="language-c">#define _FLASH_WRITE(pa, pd) { *(((u16 *)AGB_ROM)+((pa)/2)) = pd; __asm("nop"); }

// reset
_FLASH_WRITE(0, 0xF0);
Expand Down Expand Up @@ -422,7 +422,7 @@ <h2 id="erasing-a-sector"><a class="header" href="#erasing-a-sector">Erasing a S
_FLASH_WRITE(0x555, 0x56);
_FLASH_WRITE(sa, 0x30);
while (1) {
__asm(&quot;nop&quot;);
__asm("nop");
if (*(((u16 *)AGB_ROM)+(sa/2)) == 0xFFFF) {
break;
}
Expand All @@ -447,7 +447,7 @@ <h2 id="saving-data"><a class="header" href="#saving-data">Saving Data</a></h2>
_FLASH_WRITE(0xAAA, 0xA0);
_FLASH_WRITE(sa+i, (*(u8 *)(AGB_SRAM+i+1)) &lt;&lt; 8 | (*(u8 *)(AGB_SRAM+i)));
while (1) {
__asm(&quot;nop&quot;);
__asm("nop");
if (*(((u16 *)AGB_ROM)+((sa+i)/2)) == ((*(u8 *)(AGB_SRAM+i+1)) &lt;&lt; 8 | (*(u8 *)(AGB_SRAM+i)))) {
break;
}
Expand All @@ -457,7 +457,7 @@ <h2 id="saving-data"><a class="header" href="#saving-data">Saving Data</a></h2>
</code></pre>
<p>The code:</p>
<ol>
<li>Issues a &quot;Program&quot; command for each 16-bit value</li>
<li>Issues a "Program" command for each 16-bit value</li>
<li>Writes the 16-bit value at the target address</li>
<li>Waits in a loop until it reads the written value*</li>
<li>Continues writing until all 16-bit values are written</li>
Expand Down
6 changes: 3 additions & 3 deletions cpu.html
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ <h1 id="cpu"><a class="header" href="#cpu">CPU</a></h1>
}
</style>
<p>This section is intended to be an overview only, detailing those aspects of the CPU which are important to understand when developing for the GBA in particular. A more thorough description of the ARM7tdmi CPU can be found in the <a href="http://www.arm.com/arm/TRMs?OpenDocument">technical reference manuals</a> on <a href="http://www.arm.com">ARM's website</a>.</p>
<p>The CPU is a 16.78 MHz ARM7tdmi RISC processor. It is a 32-bit processor but can be switched to &quot;Thumb&quot; state, which allows it to handle a special subset of 16-bit instructions that map to 32-bit counterparts. Instructions follow a three-stage pipeline: fetch, decode, execute. As a result, the <a href="#r15" title="PC">program counter</a> always points two instructions ahead of the one currently being executed.</p>
<p>The CPU is a 16.78 MHz ARM7tdmi RISC processor. It is a 32-bit processor but can be switched to "Thumb" state, which allows it to handle a special subset of 16-bit instructions that map to 32-bit counterparts. Instructions follow a three-stage pipeline: fetch, decode, execute. As a result, the <a href="#r15" title="PC">program counter</a> always points two instructions ahead of the one currently being executed.</p>
<h2 id="cpu-registers"><a class="header" href="#cpu-registers">CPU Registers</a></h2>
<p>16 registers are visible to the user at any given time, though there are 20 <a href="#banked-registers">banked registers</a> which get swapped in whenever the CPU changes to various priveleged modes. The registers visible in user mode are as follows:</p>
<ul>
Expand All @@ -214,7 +214,7 @@ <h2 id="cpu-registers"><a class="header" href="#cpu-registers">CPU Registers</a>
<p>As far as I know the other modes do not have default stack pointers.</p>
</li>
<li>
<p><strong>r14 (LR):</strong> Link Register. Used primarily to store the address following a &quot;bl&quot; (branch and link) instruction (as used in function calls)</p>
<p><strong>r14 (LR):</strong> Link Register. Used primarily to store the address following a "bl" (branch and link) instruction (as used in function calls)</p>
</li>
<li>
<p><a id="r15"></a> <strong>r15 (PC):</strong> The Program Counter. Because the ARM7tdmi uses a 3-stage pipeline, this register always contains an address which is 2 instructions ahead of the one currrently being executed. In 32-bit ARM state, it is 8 bytes ahead, while in 16-bit Thumb state it is 4 bytes ahead.</p>
Expand Down Expand Up @@ -256,7 +256,7 @@ <h2 id="processor-modes"><a class="header" href="#processor-modes">Processor Mod
</ul>
</li>
<li>
<p><strong><span id="FIQ">FIQ</span>:</strong> This mode is entered when a Fast Interrupt Request is triggered. Since all of the hardware interrupts on the GBA generate IRQs, this mode goes unused by default, though it would be possible to switch to this mode manually using the &quot;msr&quot; instruction.</p>
<p><strong><span id="FIQ">FIQ</span>:</strong> This mode is entered when a Fast Interrupt Request is triggered. Since all of the hardware interrupts on the GBA generate IRQs, this mode goes unused by default, though it would be possible to switch to this mode manually using the "msr" instruction.</p>
<ul>
<li>Banked registers: r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq, r13_fiq, r14_fiq, and SPSR_fiq.</li>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion graphics.html
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ <h2 id="video-modes"><a class="header" href="#video-modes">Video Modes</a></h2>
<p>Exactly what the GBA draws on screen depends largely on the current video mode (also sometimes referred to as the <em>screen mode</em> or <em>graphics mode</em>). The GBA has 6 such modes, some of which are bitmap-based and some of which are tile-based. The video mode is set by the bottom three bits of the hardware register known as <a href="registers.html#REG_DISPCNT">REG_DISPCNT</a>. Background data is handled differently depending on what mode is enabled. Backgrounds can either be <a href="backgrounds.html#text-backgrounds">text backgrounds</a> (tile based), <a href="backgrounds.html#scalerotate-backgrounds">rotate-scale backgrounds</a> (tile based backgrounds that can be transformed), or <a href="backgrounds.html#bitmapped-backgrounds">bitmap backgrounds</a>. The number of sprites available on screen is also dependent on the mode; modes with tile-based backgrounds support 128 sprites, while modes with bitmapped backgrounds will only support 64 sprites.</p>
<p>Enabling objs and one or more backgrounds in <a href="registers.html#REG_DISPCNT">REG_DISPCNT</a> will cause the GBA to draw the specified backgrounds and objs in order of priority.</p>
<h3 id="mode-0"><a class="header" href="#mode-0">Mode 0</a></h3>
<p>In this mode, four text background layers can be shown. In this mode backgrounds 0 - 3 all count as <a href="backgrounds.html#text-backgrounds">&quot;text&quot;</a> backgrounds, and cannot be scaled or rotated. Check out the section on <a href="backgrounds.html#text-backgrounds">text backgrounds</a> for details on this.</p>
<p>In this mode, four text background layers can be shown. In this mode backgrounds 0 - 3 all count as <a href="backgrounds.html#text-backgrounds">"text"</a> backgrounds, and cannot be scaled or rotated. Check out the section on <a href="backgrounds.html#text-backgrounds">text backgrounds</a> for details on this.</p>
<h3 id="mode-1"><a class="header" href="#mode-1">Mode 1</a></h3>
<p>This mode is similar in most respects to Mode 0, the main difference being that only 3 backgrounds are accessible -- 0, 1, and 2. Bgs 0 and 1 are <a href="backgrounds.html#text-backgrounds">text backgrounds</a>, while bg 2 is a <a href="backgrounds.html#scalerotate-backgrounds">rotation/scaling</a> background.</p>
<h3 id="mode-2"><a class="header" href="#mode-2">Mode 2</a></h3>
Expand Down
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ <h2 id="the-basics"><a class="header" href="#the-basics">The Basics</a></h2>
<li><a href="memory.html">Memory</a> - 8 to 11 distinct areas of memory (depending on the Game Pak).</li>
<li><a href="registers.html">IO</a> - Special hardware functions available to the programmer, primarily pertaining to graphics, sound, DMA, timers, serial communication, key input, and interrupts.</li>
</ul>
<p>Programs run on the GBA are usually contained in a &quot;Game Pak&quot;. A &quot;Game Pak&quot; consists mainly of <a href="memory.html#game-pak-rom">ROM</a> and possibly <a href="memory.html#cart-ram">Cart RAM</a> (in the form of SRAM, Flash ROM, or EEPROM, used mainly for save game info). The ROM is where compiled code and data is stored. Unlike home computers, workstations, or servers, there are no disks or other drives, so everything that might otherwise have been stored as separate resource files must be compiled into the program ROM itself. Luckily there are tools to aid in this process.</p>
<p>The primary means a program accesses specialized hardware for graphics, sound, and other IO is through the <a href="registers.html">memory-mapped IO</a>. Memory mapped IO is a means of communicating with hardware by writing to/reading from specific memory addresses that are &quot;mapped&quot; to internal hardware functions. For example, you might write to address <a href="registers.html#REG_DISPCNT">0x04000000</a> with the value &quot;0x0100&quot;, which tells the hardware &quot;enable background 0 and graphics mode 0&quot;. A secondary means is through the <a href="memory.html#system-rom">BIOS</a>, which is embedded in the internal GBA system ROM. Using <a href="bios.html">software interrupts</a> it is possible to access pre-programmed (and hopefully optimized) routines lying in the the system ROM. These routines then access the hardware through the memory-mapped IO.</p>
<p>Programs run on the GBA are usually contained in a "Game Pak". A "Game Pak" consists mainly of <a href="memory.html#game-pak-rom">ROM</a> and possibly <a href="memory.html#cart-ram">Cart RAM</a> (in the form of SRAM, Flash ROM, or EEPROM, used mainly for save game info). The ROM is where compiled code and data is stored. Unlike home computers, workstations, or servers, there are no disks or other drives, so everything that might otherwise have been stored as separate resource files must be compiled into the program ROM itself. Luckily there are tools to aid in this process.</p>
<p>The primary means a program accesses specialized hardware for graphics, sound, and other IO is through the <a href="registers.html">memory-mapped IO</a>. Memory mapped IO is a means of communicating with hardware by writing to/reading from specific memory addresses that are "mapped" to internal hardware functions. For example, you might write to address <a href="registers.html#REG_DISPCNT">0x04000000</a> with the value "0x0100", which tells the hardware "enable background 0 and graphics mode 0". A secondary means is through the <a href="memory.html#system-rom">BIOS</a>, which is embedded in the internal GBA system ROM. Using <a href="bios.html">software interrupts</a> it is possible to access pre-programmed (and hopefully optimized) routines lying in the the system ROM. These routines then access the hardware through the memory-mapped IO.</p>
<p>Other regions of memory that are directly mapped to the hardware are <a href="memory.html#palette-ram">Palette RAM</a> (which is a table consisting of all the available colors), <a href="memory.html#vram">VRAM</a> (which performs a similar function to the video RAM on a PC - and thensome), and <a href="memory.html#oam">OAM</a> (which contains the attributes for hardware accelerated sprites).</p>
<h2 id="programming-for-the-gba"><a class="header" href="#programming-for-the-gba">Programming for the GBA</a></h2>
<p>C, C++, and ARM/Thumb assembly are the most common languages used in GBA development, mainly because they are fast and relatively low level (i.e. there is a large degree of correspondance between the structure of the language and underlying instruction set of the architecture).</p>
Expand Down
Loading

0 comments on commit f23263a

Please sign in to comment.