memory#
Section Constants#
These are to be used with the codegenDecl pragma to place your variables and procedures into certain regions of memory. They cannot be used for local variables, as those are always on the stack which is in IWRAM.
Example:
# Define an array which is statically allocated in EWRAM.
var collisionGrid {.codegenDecl: DataInEwram.}: array[2048, uint16]
- const DataInIwram = "__attribute__((section(\".iwram.data\"))) $# $#"#
Put variable in IWRAM (default).
- const DataInEwram = "__attribute__((section(\".ewram.data\"))) $# $#"#
Put variable in EWRAM
- const ArmCodeInIwram = "__attribute__((section(\".iwram.text\"), target(\"arm\"), long_call)) $# $#$#"#
Put procedure in IWRAM.
- const ThumbCodeInEwram = "__attribute__((section(\".ewram.text\"), target(\"thumb\"), long_call)) $# $#$#"#
Put procedure in EWRAM.
Memory-mapped arrays#
- var romMem: array[0x1000000, uint16]#
Access to ROM as an array of halfwords.
The max ROM size is
32MiB
.
- var sramMem: array[0x10000, uint8]#
Access to SRAM as an array of bytes.
This has a maximum size of
64KiB
, though many carts don’t actually have that much available.
Types#
These types are used with the waitcnt register.
Note
On Nim 1.6 and later, you can omit the enum prefixes as long as you enable overloadable enums.
In other words, you can write N3_S1
instead of WsRom0.N3_S1
.
- type WsSram = enum#
SRAM access timings
- type WsRom0 = enum#
ROM access timings.
Initial access to ROM takes
N
cycles, sequential access takesS
cycles.For more information on
N
cycles andS
cycles, see the asm chapter of Tonc.
- type WsRom1 = enum#
Access timings for ROM mirror starting at
0x0A000000
.
- type WsRom2 = enum#
Access timings for ROM mirror starting at
0x0C000000
.
- type WsPhi = enum#
PHI Terminal Output. This allows the GBA to supply a clock signal to the cartridge hardware, but is not used in practise.
- type WaitCnt = object#
Waitstate control
I/O Registers#
- var waitcnt: WaitCnt#
Waitstate control register.
This controls the number of CPU cycles taken to access cart memory (ROM and SRAM).
The “standard” setting (used by most commercial games) is as follows:
waitcnt.init( sram = WsSram.N8_S8, # 8 cycles to access SRAM. rom0 = WsRom0.N3_S1, # 3 cycles to access ROM, or 1 cycle for sequential access. rom2 = WsRom2.N8_S8, # 8 cycles to access ROM (mirror #2) which may be used for flash storage. prefetch = true # prefetch buffer enabled. )
In this example,
waitcnt.rom0
determines the access time for the default view into ROM.Warning
The preferred access time of “3,1” works on every flashcart except for the SuperCard SD and its derivatives. If you want to support the SuperCard without compromising performance for all, use the slowGamePak proc.
There are two additional ROM mirrors located at
0x0A000000
and0x0C000000
, which have access times determined bywaitcnt.rom1
andwaitcnt.rom2
.The mirrors may be useful for carts containing multiple ROM chips. For example on some carts the upper 128KiB of ROM is mapped to flash storage which would require different access timings.
Procedures#
- proc slowGamePak(): bool#
Check if the cartridge does not support fast ROM access, which might be the case if the game is running on the SuperCard MiniSD.
Example:
if slowGamePak(): waitcnt.init(rom0 = WsRom0.N4_S2) else: waitcnt.init(rom0 = WsRom0.N3_S1)