フォーマット | 7 |対応機種 | 8 |
---|---|
PAR | 13 |
14 | 日本: プロアクションリプレイ 15 | 米: GameShark v1/v2 16 | ヨーロッパ: AR GBX v1/v2 17 | |
18 |
ARv3 | 21 |
22 | 米: GameShark v3 23 | ヨーロッパ: AR GBX v3 24 | |
25 |
CB | 28 |X-TA, CodeBreaker | 29 |
VBA | 32 |VisualBoyAdvance | 33 |
Master Code #1 | 9 |
10 | 11 | xxxx is the CRC value (the "Game ID" converted to hex) 12 | address = ((d << 0x16) + 0x08000100) 13 | 14 | Flags ("yyyy"): 15 | 0008 - CRC Exists (CRC is used to autodetect the inserted game) 16 | 0002 - Disable Interupts 17 | 18 | |
19 | |
22 | 0000xxxx yyyy
23 | 1aaaaaaa 0007
24 | |
25 | ||
単純書き込み(8bit) | 29 |
30 | 31 | RAMアドレス aaaaaaa に8bit値yy を連続的に書き込みつづけます。
32 | 33 | |
34 | |
3aaaaaaa 00yy |
37 | ||
Slide Code | 41 |
42 | 43 | 2行で1つの改造コードです。 44 | アドレス aaaaaaa を始点として、16bit値yyyy をxxxxxxxx 回、書き込みます。45 | 書き込みのたびにアドレスが iiii だけインクリメントされます。46 | この改造コードは、通常、特定の値でメモリを埋めるために使用されます。 47 | |
48 | |
51 | 4aaaaaaa yyyy
52 | xxxxxxxx iiii
53 | |
54 | ||
16-Bit Logical AND | 58 |
59 | 60 | Performs the AND function on the address provided with the value provided. 61 | I'm not going to explain what AND does, so if you'd like to know I suggest you see the instruction manual for a graphing calculator. 62 | This is another advanced code type you'll probably never need to use. 63 | |
64 | |
6aaaaaaa yyyy |
67 | ||
条件比較 | 71 |
72 | 73 | アドレス aaaaaaa のデータと、16bit値yyyy に対して、条件(c )に合致する場合のみ次の行の改造コードを実行します。
74 | 75 | c : 7: =、A: ≠、B: >、C: <、 D: and (yyyy が右辺)
76 | 77 | |
78 | |
7aaaaaaa yyyy |
81 | ||
単純書き込み(16bit) | 85 |
86 | 87 | RAMアドレス aaaaaaa に16bit値yyyy を連続的に書き込みつづけます。
88 | 89 | |
90 | |
8aaaaaaa yyyy |
93 | ||
Change Encryption Seeds (When 1st Code Only!) |
97 | Works like the DEADFACE on GSA. Changes the encryption seeds used for the rest of the codes. |
98 | |
9yyyyyyy yyyy |
101 | ||
キー入力判定書き込み | 105 |
106 | 107 | yyyy と16bitのキー入力値に対して条件(c )を満たすときに、次の行の改造コードを実行します。108 | 16bitのキー入力値、KEYINPUTと同じbit配置ですがキーが押されているときに1になります。 109 | c : 1: ≠, 2: =
110 | |
111 | |
D00000c0 yyyy |
114 |
4 | Note: 5 | 6 | この記事は 7 | 8 | - Decoding the ARM instruction set 9 | - Decoding the THUMB instruction set 10 | 11 | を翻訳したもので、主にGBAエミュレータ開発者向けです。 12 |13 | 14 | ## ARMモード 15 | 16 | まず、ARM命令のバイナリオペコードフォーマットを見てみましょう。 17 | 18 |  19 | 20 | しかし、この参考文献は完全に正確なものではなく、最初の命令をデコードするために必要な重要な情報を見逃しているので、これから説明します。 21 | 22 | まず最初に、THUMB命令セットをデコードするとき、私たちは単純に命令の上位8ビットを使用していたので、命令を明確にデコードすることができました。 23 | 24 | 例えば、ビット27~20を使って、どの命令なのかを判断しようとすると、ビット27~20をすべてアンセット(0)にする命令が複数種類あるため、曖昧になってしまいます。 25 | 26 | そこで、上位8ビット(ビット27-20)とベース4ビット(ビット7-4)を端と端で足し合わせることにします。この原理をもう少しわかりやすく説明するための絵があります。 27 | 28 |  29 | 30 | C/C++では、この値を実際に取得するには、ビット単位での微調整が必要です。例えば、以下のようになります。 31 | 32 | ```cpp 33 | u32 instruction = fetch(); 34 | u16 _12Bits = (((instruction >> 16) & 0xFF0) | ((instruction >> 4) & 0x0F)); 35 | ``` 36 | 37 | これで、命令をデコードするのに使う12ビットの数字ができました。では、最初から考えてみましょう。 38 | 39 | この12ビットの数字が0、つまりすべてのビットがアンセットされていたらどうなるでしょうか。 40 | 41 | オペコードフォーマットを見ると、これを可能にする命令フォーマットは1つだけで、1枚目の写真の一番上の`Data Processing/PSR`命令であることがわかります。 42 | 43 | さて、この命令がどのようなタイプの命令であるかはすでにわかっていますが、どのような命令であるかを正確に知るためには、さらに情報が必要です。 44 | 45 | `Data Processing/PSR`命令では、`Operand2`というフィールドがあります。 46 | 47 | このフィールドは、上記のバイナリオペコードフォーマットには示されていないフォーマットを持っており、以下に`Operand2`フィールドの仕様を示します。 48 | 49 |  50 | 51 | 今回の状況では、すべてのビットは0なので、当然`immediate`ビット(bit25)がセットされていないので、シフトされたレジスタを使用していることになります。 52 | 53 | バレルシフトについては今のところ説明しませんが、これはこの記事の範囲を超えています。ここでは、より正式な言い方として、マニュアルから直接引用します。 54 | 55 | > 第2オペランドがシフトレジスタと指定されている場合、バレルシフタの動作は命令の`shift`フィールドによって制御されます。 56 | 57 | `shift`フィールドは次のようになっています。 58 | 59 |  60 | 61 | これは非常に複雑なことだと思いますが、マニュアルを読んでいただくのが一番です。 62 | 63 | とにかく、私についてきてください。この命令について、これまでに集めた情報を確認してみましょう。12ビットすべてが0であると仮定すると...。 64 | 65 | 1. `Data Processing`命令です。 66 | 2. シフトされたレジスタのバレルシフト演算を使用します。 67 | 3. bit24-21からAND命令です。 68 | 4. bit4は0なので、シフトしたレジスタを即値でシフトするシフト操作であることがわかり、直前の図の左側のフォーマットを使用しています。 69 | 5. bit6-5は0なので、シフト内容は`LSL`です。 70 | 71 | よって 72 | 73 | `AND Rd, Rn, Rm, LSL #imm5` 74 | 75 | となります! 76 | 77 | ## THUMBモード 78 | 79 | まず、THUMB命令のバイナリオペコードフォーマットを見てみましょう。 80 | 81 |  82 | 83 | 各命令は2バイト(ハーフワード)で構成されており、各命令には、CPUがデコードする独自のフォーマットがあります。 84 | 85 | ご覧のように、フォーマット1(`Move shifted register`)のようないくつかの命令フォーマットには、これが特定の命令であることを示すオペコードフィールドがあります。`Move shifted register`の場合には、12-11bitに2ビットのオペコードフィールドがあります。 86 | 87 | さて、私が命令をデコードする方法は、命令の上位8ビットを取り、その値をチェックすることです。 88 | 89 | 例えば、上位8ビットの値が「0〜7」であれば、その命令が`LSL Rd, Rs, Offset`とわかります。なぜでしょうか? 90 | 91 | これは、上位8ビットが「0〜7」になっている間は、`Move shifted register`のオペコードフィールドが0になり、この形式の他のビットはすべて正しいからです。 92 | 93 |  94 | 95 | 上の図では上位8bitは`00000101`となっています。 96 | 97 | 命令フォーマットを確認すると、`Move shifted register`フォーマットでは、上位8bitがこの値になる場合がありえます。 98 | 99 | `Move shifted register`フォーマットでは、先の8bit値の下位3bitが、`Offset5`フィールドの上位3bit(bit8,9,10)であり、このフィールドは任意の値がありうるからです。 100 | 101 | また、任意の値をとりうるということは、次の8つのバイナリはすべて`LSL Rd, Rs, Offset5`となります。 102 | 103 | ``` 104 | 00000000 (0) 105 | 00000001 (1) 106 | 00000010 (2) 107 | 108 | 00000011 (3) 109 | 00000100 (4) 110 | 00000101 (5) 111 | 00000110 (6) 112 | 00000111 (7) 113 | ``` 114 | 115 | 次に、仮に8という値が出た場合、オペコードフィールドが1つ増えたことになるので、命令は`LSR Rd, Rs, Offset5`となります。 116 | 117 | 残りの命令セットのデコードも、この論理パターンに従うだけです。 118 | 119 | ここでは、最初の数個の命令をどのようにデコードするか、コード例を紹介します 120 | 121 | 条件分岐を使う場合は、 122 | 123 | ```cpp 124 | u16 instruction = fetch(); 125 | 126 | switch (instruction >> 8) 127 | { 128 | case 0: 129 | case 1: 130 | case 2: 131 | case 3: 132 | case 4: 133 | case 5: 134 | case 6: 135 | case 7: 136 | { 137 | // LSL Rd, Rs, Offset5 138 | } break; 139 | case 8: 140 | case 9: 141 | case 0xA: 142 | case 0xB: 143 | case 0xC: 144 | case 0xD: 145 | case 0xE: 146 | case 0xF: 147 | { 148 | // LSR Rd, Rs, Offset5 149 | } break; 150 | } 151 | ``` 152 | 153 | 関数ポインタの配列を使う場合は、 154 | 155 | ```cpp 156 | 157 | void (*CPU_Thumb_Instruction[0x100]) (u16 instruction) = 158 | { 159 | Thumb_LSL_Rd_Rs_Offset, // 00h 160 | Thumb_LSL_Rd_Rs_Offset, // 01h 161 | Thumb_LSL_Rd_Rs_Offset, // 02h 162 | Thumb_LSL_Rd_Rs_Offset, // 03h 163 | Thumb_LSL_Rd_Rs_Offset, // 04h 164 | Thumb_LSL_Rd_Rs_Offset, // 05h 165 | Thumb_LSL_Rd_Rs_Offset, // 06h 166 | Thumb_LSL_Rd_Rs_Offset, // 07h 167 | /*-------------------*/ 168 | Thumb_LSR_Rd_Rs_Offset, // 08h 169 | Thumb_LSR_Rd_Rs_Offset, // 09h 170 | Thumb_LSR_Rd_Rs_Offset, // 0Ah 171 | Thumb_LSR_Rd_Rs_Offset, // 0Bh 172 | Thumb_LSR_Rd_Rs_Offset, // 0Ch 173 | Thumb_LSR_Rd_Rs_Offset, // 0Dh 174 | Thumb_LSR_Rd_Rs_Offset, // 0Eh 175 | Thumb_LSR_Rd_Rs_Offset, // 0Fh 176 | }; 177 | ``` 178 | 179 | -------------------------------------------------------------------------------- /others/homebrew/devkit.md: -------------------------------------------------------------------------------- 1 | # devkitProのインストール手順(MacOS) 2 | 3 | 1. [ここ](https://github.com/devkitPro/pacman/releases/tag/v1.0.2)から[`devkitpro-pacman-installer.pkg`](https://github.com/devkitPro/pacman/releases/download/v1.0.2/devkitpro-pacman-installer.pkg)をダウンロード 4 | 2. ダウンロードした`devkitpro-pacman-installer.pkg`をfinder上で右クリックして『開く』を押してインストール 5 | 3. 再起動 6 | 4. `sudo (dkp-)pacman -S gba-dev` 7 | 8 | -------------------------------------------------------------------------------- /others/homebrew/mgba_with_gdb.md: -------------------------------------------------------------------------------- 1 | # mgbaをgdbでデバッグする方法 2 | 3 | [Debugging With mGBA](https://simianzombie.com/posts/2018/11/12/debugging-with-mgba)を翻訳したものです。 4 | 5 | 1. ROMをmGBAで開く 6 | 2. mGBAのデバッグサーバーUIを開く(MacOSの場合は、`open Tools -> Start GDB server`) 7 | 3. オプションを指定して、`Start` 8 | 4. ターミナルを開いて、`/opt/devkitpro/devkitARM/bin/arm-none-eabi-gdb`と叩き、GDBを実行する 9 | 5. GDBのシェル内で、`target remote localhost:2345`を実行(3のオプションによって`localhost:2345`を調整してください) 10 | 6. GDBのシェル内で、`file
bit | 75 |15 | 76 |14-8 | 77 |7-0 | 78 ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
内容 | 83 |符号 | 84 |整数部分 (7 bits) | 85 |分数部分 (8 bits) | 86 |
Addr | 48 |7-6 | 49 |5 | 50 |4 | 51 |3 | 52 |2 | 53 |1 | 54 |0 | 55 ||
---|---|---|---|---|---|---|---|---|
0x0400_0050 | 60 |特殊効果 | 61 |BD/1st | 62 |OBJ/1st | 63 |BG3/1st | 64 |BG2/1st | 65 |BG1/1st | 66 |BG0/1st | 67 ||
0x0400_0051 | 70 |不使用(0) | 71 |BD/2nd | 72 |OBJ/2nd | 73 |BG3/2nd | 74 |BG2/2nd | 75 |BG1/2nd | 76 |BG0/2nd | 77 |
bit | 104 |15 | 105 |14 | 106 |13 | 107 |12 | 108 |11 | 109 |10 | 110 |9 | 111 |8 | 112 |7 | 113 |6 | 114 |5 | 115 |4 | 116 |3 | 117 |2 | 118 |1 | 119 |0 | 120 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
内容 | 125 |不使用 | 126 |EVB | 127 |不使用 | 128 |EVA | 129 |
bit | 152 |31-5 | 153 |4-0 | 154 |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
内容 | 159 |不使用 | 160 |EVY | 161 |
bit | 40 |15 | 41 |14 | 42 |13 | 43 |12 | 44 |11 | 45 |10 | 46 |9 | 47 |8 | 48 |7 | 49 |6 | 50 |5 | 51 |4 | 52 |3 | 53 |2 | 54 |1 | 55 |0 | 56 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
color | 61 |-- | 62 |Blue(0..31) | 63 |Green(0..31) | 64 |Red(0..31) | 65 |