BIOSメモリは読み出し処理に対して保護されています。
GBAは、プログラムカウンタがBIOSエリア内にある場合に限り、オペコードやデータを読み出すことができます。
プログラムカウンタがBIOSエリアにない場合に読み出しを行うと、正常にフェッチされた最新のBIOSオペコードが返ってきます。
例えば、
- 電源ON直後やソフトリセット直後は
[00DCh+8]
のオペコード - IRQハンドラの処理中は
[0134h+8]
のオペコード - IRQ終了後は
[013Ch+8]
のオペコード - SWIの処理中は
[0188h+8]
のオペコード
が帰ってきます。
Accessing unused memory at 00004000h-01FFFFFFh, and 10000000h-FFFFFFFFh (and 02000000h-03FFFFFFh when RAM is disabled via Port 4000800h) returns the recently pre-fetched opcode.
For ARM code this is simply:
WORD = [$+8]
For THUMB code the result consists of two 16bit fragments and depends on the address area and alignment where the opcode was stored.
For THUMB code in Main RAM, Palette Memory, VRAM, and Cartridge ROM this is:
LSW = [$+4], MSW = [$+4]
For THUMB code in BIOS or OAM (and in 32K-WRAM on Original-NDS (in GBA mode)):
LSW = [$+4], MSW = [$+6] ; for opcodes at 4-byte aligned locations
LSW = [$+2], MSW = [$+4] ; for opcodes at non-4-byte aligned locations
For THUMB code in 32K-WRAM on GBA, GBA SP, GBA Micro, NDS-Lite (but not NDS):
LSW = [$+4], MSW = OldHI ; for opcodes at 4-byte aligned locations
LSW = OldLO, MSW = [$+4] ; for opcodes at non-4-byte aligned locations
Whereas OldLO/OldHI are usually:
OldLO=[$+2], OldHI=[$+2]
Unless the previous opcode's prefetch was overwritten; that can happen if the previous opcode was itself an LDR opcode, ie. if it was itself reading data:
OldLO=LSW(data), OldHI=MSW(data)
Theoretically, this might also change if a DMA transfer occurs.
Note: Additionally, as usually, the 32bit data value will be rotated if the data address wasn't 4-byte aligned, and the upper bits of the 32bit value will be masked in case of LDRB/LDRH reads.
Note: The opcode prefetch is caused by the prefetch pipeline in the CPU itself, not by the external gamepak prefetch, ie. it works for code in ROM and RAM as well.
- BIOS, IO: ミラー無し
- EWRAM: 0x40000ごとに
0x02000000-0x02FFFFFF
の範囲に渡ってミラー - IWRAM: 0x8000ごとに
0x03000000-0x03FFFFFF
の範囲に渡ってミラー - Palette: 0x400ごとに
0x05000000-0x05FFFFFF
の範囲に渡ってミラー - VRAM:
0x06010000-0x06017FFF
が0x06018000-0x0601FFFF
にミラー、そして0x20000ごとに0x06000000-0x06FFFFFFF
の範囲に渡ってミラー - OAM: 0x400ごとに
0x07000000-0x07FFFFFF
の範囲に渡ってミラー - SRAM: 0x10000ごとに
0xE000000-0xFFFFFFF
の範囲に渡ってミラー
Video Memory (BG, OBJ, OAM, Palette) can be written to in 16bit and 32bit units only. Attempts to write 8bit data (by STRB opcode) won't work:
Writes to OBJ (6010000h-6017FFFh) (or 6014000h-6017FFFh in Bitmap mode) and to OAM (7000000h-70003FFh) are ignored, the memory content remains unchanged.
Writes to BG (6000000h-600FFFFh) (or 6000000h-6013FFFh in Bitmap mode) and to Palette (5000000h-50003FFh) are writing the new 8bit value to BOTH upper and lower 8bits of the addressed halfword, ie. "[addr AND NOT 1]=data*101h".
In Text mode, large tile numbers (combined with a non-zero character base setting in BGnCNT register) may exceed the available 64K of BG VRAM.
On GBA and GBA SP, such invalid tiles are displayed as if the character data is filled by the 16bit BG Map entry value (ie. as vertically striped tiles). Above applies only if there is only one BG layer enabled, with two or more layers, things are getting much more complicated: tile-data is then somehow derived from the other layers, depending on their priority order and scrolling offsets.
On NDS (in GBA mode), such invalid tiles are displayed as if the character data is zero-filled (ie. as invisible/transparent tiles).
Read
アドレスから8bitの値を取得しますが、その値には 0x0101
(LDRH),0x01010101
(LDR) が掛け算されています。
Write
対象のアドレスに対してのみ(つまり1バイト分)書き込みを行います。
書き込みたい値をval
(16 or 32bit)、対象のアドレスを4で割った余りをx
とするとval ROR (x*8)
が対象のアドレスに書き込まれます。