bios¶
This module exposes the GBA system calls (aka. BIOS functions).
The function names are PascalCase
as is the convention used by Tonc,
GBATek and others, which also conveniently helps to avoid clashing with
Nim’s reserved keywords such as div
and mod
.
Attention
These aren’t fully documented yet - please refer to GBATek in the meantime.
Types¶
- type ResetFlag = enum¶
rsEwram
– Clear 256K on-board RAM.rsIwram
– Clear 32K in-chip RAM, except for the last 0x200 bytesrsPalettes
– Clear palettesrsVram
– Clear VRAMrsOam
– Clear OAM (does not disable OBJs!)rsSio
– Reset serial registers (switches to general purpose mode)rsSound
– Reset sound registersrsRegisters
– Reset all other registers
- type ResetFlags = set[ResetFlag]¶
A bitset of flags to be passed to
RegisterRamReset
- type CpuSetMode = enum¶
csmCopy
– Copy datacsmFill
– Fill data (source pointer remains fixed)
- type CpuSetStride = enum¶
cssHalfwords
– Copy/fill by 2 bytes at a timecssWords
– Copy/fill by 4 bytes at a time
- type CpuSetOptions = distinct uint32¶
- type CpuFastSetOptions = distinct uint32¶
- type BitUnpackOptions = object¶
Field
Type
Description
srcLen
uint16 Source length (bytes)
srcBpp
uint8 Source bitdepth (1,2,4,8)
dstBpp
uint8 Destination bitdepth (1,2,4,8,16,32)
dstOffset
cuint Value added to all non-zero elements.
incZeros
bool If true,
dstOffset
will also be added to zero elements.
- type MultibootOptions = object¶
Field
Type
reserved1
array[5, uint32] handshakeData
uint8 padding
uint8 handshakeTimeout
uint16 probeCount
uint8 clientData
array[3, uint8] paletteData
uint8 responseBit
uint8 clientBit
uint8 reserved2
uint8 bootSrcp
ptr uint8 bootEndp
ptr uint8 masterp
ptr uint8 reserved3
array[3, ptr uint8] systemWork2
array[4, uint32] sendflag
uint8 probeTargetBit
uint8 checkWait
uint8 serverType
uint8
- type MultibootMode = enum¶
mbNormal
mbMulti
mbFast
Procedures¶
Resetting¶
- proc SoftReset()¶
- proc RegisterRamReset(flags: ResetFlags)¶
Performs a selective reset of memory and I/O registers.
Note
This also enables the “forced blank” bit of the display control register (
dispcnt.blank
), which will turn the screen white until you set it tofalse
.
Halting¶
- proc Halt()¶
Halts the CPU until any enabled interrupt occurs.
- proc Stop()¶
Stops the CPU and turns off the LCD until an enabled keypad, cartridge or serial interrupt occurs.
- proc IntrWait(clear: bool, irq: set[IrqIndex])¶
Wait until any one of the specified interrupts occurs.
- Clear:
If true, pre-acknowledged interrupts will be disregarded and the routine will wait for them to be acknowledged again.
- Irq:
Which interrupt(s) to wait for.
- proc VBlankIntrWait()¶
Wait for the next VBlank period.
This is equivalent to
IntrWait(true, {iiVBlank})
.If the VBlank interrupt is not enabled, then this will hang.
Example:
import natu/[irq, bios] irq.enable(iiVBlank) while true: VBlankIntrWait()
Arithmetic¶
- proc Div(num, den: cint): cint¶
Basic integer division.
- Num:
Numerator.
- Den:
Denominator.
Returns
num / den
.Note
Dividing by zero results in an infinite loop. Try
DivSafe
instead.
- proc DivArm(den, num: cint): cint¶
Basic integer division, but with switched arguments.
- Den:
Denominator.
- Num:
Numerator.
Returns
num / den
.Note
Dividing by 0 results in an infinite loop.
- proc Sqrt(num: cuint): cuint¶
Integer Square root.
- proc ArcTan(dydx: FixedT[int16,14]): int16¶
Arctangent of dy/dx.
Takes a 2.14 fixed-point value representing the steepness of the slope.
Returns an angle in the range
-0x4000..0x4000
(representing -𝜋/2 to 𝜋/2).Warning
This gives completely wrong results for inputs outside the range
-0x2000..0x2000
(-1.0 to 1.0).As such, it can only effectively return angles in the range
-0x2000..0x2000
(-𝜋/4 to 𝜋/4).Consider using
ArcTan2
instead.
- proc ArcTan2(x, y: int16): uint16¶
Full-circle arctangent of a coordinate pair.
+Y │ . (x,y) │ / │/╮θ -X ────────┼──────── +X │ │ │ -Y
This calculates the angle between the positive X axis and the point
(x, y)
.The value returned is in the range
0x0000..0xffff
(0 to 2𝜋).Warning
In most mathematical libraries the parameters to atan2 are ordered as
y, x
, but here they’rex, y
.
Memory copy / fill¶
- proc CpuSet(src: pointer, dst: pointer, opts: CpuSetOptions)¶
Transfer via CPU in word/halfword chunks.
The default mode is 16-bit copies.
When
opts.mode == cmFill
it will keep the source address constant, effectively performing fills instead of copies.When
opts.stride == csWords
it will copy or fill in 32-bit steps instead.- Src:
Source address.
- Dst:
Destination address.
- Opts:
Number of transfers, mode and stride.
Note
This basically does a straightforward loop-copy, and is not particularly fast.
In fill-mode, the source is still an address, not a value.
- proc CpuFastSet(src: pointer, dst: pointer, opts: CpuFastSetOptions)¶
A fast transfer via CPU in 32 byte chunks.
This uses ARM’s ldmia/stmia instructions to copy 8 words at a time, making it rival DMA transfers in speed.
When
opts.mode == cmFill
it will keep the source address constant, effectively performing fills instead of copies.- Src:
Source address. Must be word aligned.
- Dst:
Destination address. Must be word aligned.
- Opts:
Number of words to transfer, and mode.
Note
Both source and destination must be word aligned; the number of copies must be a multiple of 8.
In fill-mode, the source is still an address, not a value.
memcpy32
/16
andmemset32
/16
basically do the same things, but safer. Use those instead.
Checksum¶
- proc BiosCheckSum(): uint32¶
Calculate the checksum of the BIOS.
Returns:
0xbaae187f
for GBA / GBA SP / Game Boy Micro / Game Boy Player0xbaae1880
for DS / DS Lite / DSi / 3DS Family.
Rotation / scaling¶
These procedures are misnomers, because ObjAffineSet
is merely a special case of BgAffineSet
. Results from either can be used for both objs and bgs.
- proc ObjAffineSet(src: ptr ObjAffineSource, dst: pointer, num: cint, offset: cint)¶
Sets up a simple scale-then-rotate affine transformation. Uses a single
ObjAffineSource
struct to set up an array of affine matrices (either BG or Object) with a certain transformation. The matrix created is:┌───────────┬────────────┐ | sx·cos(α) | -sx·sin(α) | ├───────────┼────────────┤ | sy·sin(α) | sy·cos(α) | └───────────┴────────────┘
- Src:
Array with scale and angle information.
- Dst:
Array of affine matrices, starting at a
pa
element.- Num:
Number of matrices to set.
- Offset:
Offset between affine elements. Use 2 for BG and 8 for object matrices.
Note
Each element in
src
needs to be word aligned.
- proc BgAffineSet(src: ptr BgAffineSource, dst: ptr BgAffineDest, num: cint)¶
Sets up a simple scale-then-rotate affine transformation. See
ObjAffineSet
for more information.
Decompression¶
(see GBATek for format details)
- proc BitUnPack(src: pointer, dst: pointer, bup: BitUnpackOptions)¶
- proc LZ77UnCompWram(src: pointer, dst: pointer)¶
- proc LZ77UnCompVram(src: pointer, dst: pointer)¶
- proc HuffUnComp(src: pointer, dst: pointer)¶
- proc RLUnCompWram(src: pointer, dst: pointer)¶
- proc RLUnCompVram(src: pointer, dst: pointer)¶
- proc Diff8bitUnFilterWram(src: pointer, dst: pointer)¶
- proc Diff8bitUnFilterVram(src: pointer, dst: pointer)¶
- proc Diff16bitUnFilter(src: pointer, dst: pointer)¶
Sound¶
- proc SoundBias(bias: uint32)¶
- proc SoundDriverInit(src: pointer)¶
- proc SoundDriverMode(mode: uint32)¶
- proc SoundDriverMain()¶
- proc SoundDriverVSync()¶
- proc SoundChannelClear()¶
- proc MidiKey2Freq(wa: pointer, mk: uint8, fp: uint8): uint32¶
- proc MultiBoot(mb: MultibootOptions, mode: MultibootMode): cint¶
Multiboot handshake
- proc HardReset()¶
Reboots the GBA, including playing through the GBA boot intro.
- proc SoundDriverVSyncOff()¶
- proc SoundDriverVSyncOn()¶
Extras¶
Additional utilities from Tonc which are built atop the BIOS routines.
- proc VBlankIntrDelay(count: cuint)¶
Wait for
count
frames.
- proc DivSafe(num, den: cint): cint¶
Divide-by-zero safe division.
The standard
Div
hangs whenden == 0
. This version will returncint.high
orcint.low
, depending on the sign ofnum
.- Num:
Numerator.
- Den:
Denominator.
Returns
num / den
.
- proc Mod(num, den: cint): cint¶
Modulo:
num % den
.
- proc DivMod(num, den: cint): cint¶
Modulo:
num % den
.
- proc DivAbs(num, den: cint): cuint¶
Absolute value of
num / den
.
- proc DivArmMod(den, num: cint): cint¶
Modulo:
num % den
.
- proc DivArmAbs(den, num: cint): cuint¶
Absolute value of
num / den
.
- proc CpuFastFill(wd: uint32, dst: pointer, words: cuint)¶
A fast word fill.
While you can perform fills with
CpuFastSet
, the fact that swi0x01
requires a source address makes it awkward to use. This function is more like the traditional memset formulation.- Wd:
Fill word.
- Dst:
Destination address.
- Words:
Number of words to transfer.