- 追加された行はこの色です。
- 削除された行はこの色です。
- doc.6 へ行く。
#author("2023-05-29T23:53:17+09:00","","")
#author("2023-05-29T23:53:49+09:00","","")
* BIOS [#k6ecb6cf]
GBAのSystem ROM(BIOS)には、あらかじめ用意されているいくつかの機能があります。具体的には次のようなものです。
- Arithmetic Functions
- Rotation/Scaling Functions
- Decompression Functions
- Memory Copy
- Halt Functions
- Reset Functions
- Multi Boot (Single Game Pak)
- Sound Functions
BIOS Function Summary
SWI Hex Function
0 00h SoftReset
1 01h RegisterRamReset
2 02h Halt
3 03h Stop
4 04h IntrWait
5 05h VBlankIntrWait
6 06h Div
7 07h DivArm
8 08h Sqrt
9 09h ArcTan
10 0Ah ArcTan2
11 0Bh CpuSet
12 0Ch CpuFastSet
13 0Dh -Undoc- ("GetBiosChecksum")
14 0Eh BgAffineSet
15 0Fh ObjAffineSet
16 10h BitUnPack
17 11h LZ77UnCompWram
18 12h LZ77UnCompVram
19 13h HuffUnComp
20 14h RLUnCompWram
21 15h RLUnCompVram
22 16h Diff8bitUnFilterWram
23 17h Diff8bitUnFilterVram
24 18h Diff16bitUnFilter
25 19h SoundBias
26 1Ah SoundDriverInit
27 1Bh SoundDriverMode
28 1Ch SoundDriverMain
29 1Dh SoundDriverVSync
30 1Eh SoundChannelClear
31 1Fh MidiKey2Freq
32-36 20h-24h -Undoc- (Sound Related ???)
37 25h MultiBoot
38 26h -Undoc- ("HardReset")
39 27h -Undoc- ("CustomHalt")
40 28h SoundDriverVSyncOff
41 29h SoundDriverVSyncOn
42 2Ah -Undoc- ("GetJumpList" for Sound ???)
43-255 2Bh-FFh -Not used-
The BIOS SWI handler does not perform any range checks,
so calling SWI 43-255 will blindly lock up the GBA.
この機能群はC言語でいうところの関数の集まりと思ってください。ただ呼び出し方法が少し特殊で、CPUのSWI命令と機能番号を使います。SWI 43-255はコールしないでください。フリーズすると思って構いません。
** LZ77UnCompVram [#o082559f]
使用例として機能番号18(12h)のLZ77UnCompVramを使います。この機能は''LZ77圧縮された画像ファイルを解凍しつつ、指定されたメモリ領域に展開する機能''です。LZ77のアルゴリズムについては[[google先生:https://www.google.com/search?q=LZ77]]に聞いてみてください。~
作業の順番としては~
- 1.LZ77圧縮された画像ファイルを作成
- 2.BIOSを呼び出す関数(main)を作成
- 3.コンパイル&実行
となります。
*** LZ77圧縮された画像ファイルを用意する [#ce7bdf93]
ここではdevkitProに標準で用意されているgritを使用します。コマンドのオプションに''-gzl''を付け加えることでLZ77圧縮の指定になります。ちなみにGBAでデータを圧縮して使いたい場合、脳死でこのフォーマットを選んで構いません。
- モード3 240x160サイズの画像の場合
- モード3 240x160サイズ
| 無圧縮 | 76800バイト | 100% |
| LZ77 | 16968バイト | 22% |
*** BIOSを呼び出すコードを用意する [#d8b1a14d]
仕様についてはGBATEKより抜粋してきたものを以下に表します。
SWI 17 (11h) - LZ77UnCompWram
SWI 18 (12h) - LZ77UnCompVram
Expands LZ77-compressed data. The Wram function is faster, and writes in units of 8bits.
For the Vram function the destination must be halfword aligned, data is written in units of 16bits.
If the size of the compressed data is not a multiple of 4,
please adjust it as much as possible by padding with 0.
Align the source address to a 4-Byte boundary.
r0 Source address, pointing to data as such:
Data header (32bit)
Bit 0-3 Reserved
Bit 4-7 Compressed type (must be 1 for LZ77)
Bit 8-31 Size of decompressed data
Repeat below. Each Flag Byte followed by eight Blocks.
Flag data (8bit)
Bit 0-7 Type Flags for next 8 Blocks, MSB first
Block Type 0 - Uncompressed - Copy 1 Byte from Source to Dest
Bit 0-7 One data byte to be copied to dest
Block Type 1 - Compressed - Copy N+3 Bytes from Dest-Disp-1 to Dest
Bit 0-3 Disp MSBs
Bit 4-7 Number of bytes to copy (minus 3)
Bit 8-15 Disp LSBs
r1 Destination address
Return: No return value.
引数には転送元のアドレス(r0)と転送先のアドレス(r1)が必要です。早速、コードを作成していきましょう。
- gba.h
#if defined ( __thumb__ )
#define SystemCall(Number) __asm ("SWI "#Number"\n" ::: "r0", "r1", "r2", "r3")
#else
#define SystemCall(Number) __asm ("SWI "#Number" << 16\n" :::"r0", "r1", "r2", "r3")
#endif
- sys_arm.c
IWRAM_CODE void LZ77UnCompVram(void *source, void *dest)
{
SystemCall(18);
}
*** 呼び出し側の関数を用意する [#p1f877f7]
#include "lib/gba.h"
#include "res.h"
//---------------------------------------------------------------------------
void WaitForVsync(void)
{
while (*(volatile u16*)0x4000006 >= 160) {};
while (*(volatile u16*)0x4000006 < 160) {};
}
//---------------------------------------------------------------------------
int main(void)
{
SetMode(MODE_3 | BG2_ENABLE);
LZ77UnCompVram((void*)&imageBitmap, (void*)VRAM);
for(;;)
{
WaitForVsync();
}
}
*** 動作画面 [#n1a6659a]
#ref(1.png,nolink)
** 履歴 [#s309c1fc]
- 2023/04/14
- 2007/09/19