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
srcLenuint16 Source length (bytes)
srcBppuint8 Source bitdepth (1,2,4,8)
dstBppuint8 Destination bitdepth (1,2,4,8,16,32)
dstOffsetcuint Value added to all non-zero elements.
incZerosbool If true,
dstOffsetwill also be added to zero elements.
- type MultibootOptions = object¶
Field
Type
reserved1array[5, uint32] handshakeDatauint8 paddinguint8 handshakeTimeoutuint16 probeCountuint8 clientDataarray[3, uint8] paletteDatauint8 responseBituint8 clientBituint8 reserved2uint8 bootSrcpptr uint8 bootEndpptr uint8 masterpptr uint8 reserved3array[3, ptr uint8] systemWork2array[4, uint32] sendflaguint8 probeTargetBituint8 checkWaituint8 serverTypeuint8
- type MultibootMode = enum¶
mbNormalmbMultimbFast
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
DivSafeinstead.
- 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
ArcTan2instead.
- proc ArcTan2(x, y: int16): uint16¶
Full-circle arctangent of a coordinate pair.
+Y │ . (x,y) │ / │/╮θ -X ────────┼──────── +X │ │ │ -YThis 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 == cmFillit will keep the source address constant, effectively performing fills instead of copies.When
opts.stride == csWordsit 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 == cmFillit 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/16andmemset32/16basically do the same things, but safer. Use those instead.
Checksum¶
- proc BiosCheckSum(): uint32¶
Calculate the checksum of the BIOS.
Returns:
0xbaae187ffor GBA / GBA SP / Game Boy Micro / Game Boy Player0xbaae1880for 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
ObjAffineSourcestruct 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
paelement.- Num:
Number of matrices to set.
- Offset:
Offset between affine elements. Use 2 for BG and 8 for object matrices.
Note
Each element in
srcneeds to be word aligned.
- proc BgAffineSet(src: ptr BgAffineSource, dst: ptr BgAffineDest, num: cint)¶
Sets up a simple scale-then-rotate affine transformation. See
ObjAffineSetfor 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
countframes.
- proc DivSafe(num, den: cint): cint¶
Divide-by-zero safe division.
The standard
Divhangs whenden == 0. This version will returncint.highorcint.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 swi0x01requires 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.