gba-link-connection/examples/_lib/libugba/include/bios.h
2022-05-20 05:30:56 -03:00

208 lines
7.7 KiB
C

// SPDX-License-Identifier: MIT
//
// Copyright (c) 2020, 2022 Antonio Niño Díaz
#ifndef BIOS_H__
#define BIOS_H__
#include <assert.h>
#include "definitions.h"
#include "hardware.h"
// Note: Names taken from GBATEK
// Perform a soft reset. Not supported on the SDL2 port.
EXPORT_API NORETURN void SWI_SoftReset(void);
// Flags to use with SWI_RegisterRamReset()
#define SWI_RAM_RESET_EWRAM (1 << 0)
#define SWI_RAM_RESET_IWRAM (1 << 1) // Except for the last 0x200 bytes
#define SWI_RAM_RESET_PALETTE (1 << 2)
#define SWI_RAM_RESET_VRAM (1 << 3)
#define SWI_RAM_RESET_OAM (1 << 4)
#define SWI_RAM_RESET_IO_SERIAL (1 << 5)
#define SWI_RAM_RESET_IO_SOUND (1 << 6)
#define SWI_RAM_RESET_IO_OTHER (1 << 7)
// Clear different areas of memory and I/O registers
EXPORT_API void SWI_RegisterRamReset(uint32_t flags);
// Wait until an interrupt happens.
EXPORT_API void SWI_Halt(void);
// Wait until the VBlank interrupt happens.
EXPORT_API void SWI_VBlankIntrWait(void);
// Wait for any of the interrupts in the flags specified. If an interrupt has
// already happened, it is possible to discard it by setting the argument to 1.
// If it is set to 0, and the interrupt has happened already, this function will
// return right away.
//
// Note that if no flags are passed the CPU will stay in an infinite loop inside
// this function.
EXPORT_API void SWI_IntrWait(uint32_t discard_old_flags, uint16_t wait_flags);
// For SWI_CpuSet() and SWI_CpuFastSet()
#define SWI_MODE_COPY (0 << 24)
#define SWI_MODE_FILL (1 << 24)
// For SWI_CpuSet() only
#define SWI_MODE_16BIT (0 << 26)
#define SWI_MODE_32BIT (1 << 26)
// Source and destination must be aligned to 4 bytes for 32-bit copies, or 2
// bytes for 16-bit copies. The length is expressed either in 32-bit or 16-bit
// chunks (words or halfwords).
EXPORT_API void SWI_CpuSet(const void *src, void *dst, uint32_t len_mode);
// Source and destination must be aligned to 4 bytes. The length must be a
// multiple of 8 bytes.
EXPORT_API void SWI_CpuFastSet(const void *src, void *dst, uint32_t len_mode);
// Calculate result or modulus of dividing num by div.
EXPORT_API int32_t SWI_Div(int32_t num, int32_t div);
EXPORT_API int32_t SWI_DivMod(int32_t num, int32_t div);
// Calculate square root.
EXPORT_API uint16_t SWI_Sqrt(uint32_t value);
// Calculate arc tangent
EXPORT_API int16_t SWI_ArcTan(int16_t tan);
// Calculate arc tangent 2
EXPORT_API int16_t SWI_ArcTan2(int16_t x, int16_t y);
// Known values that SWI_GetBiosChecksum() can return
#define SWI_CHECKSUM_GBA (0xBAAE187F) // GBA, GBA SP, GB Micro
#define SWI_CHECKSUM_NDS (0xBAAE1880) // NDS, 3DS in NDS mode
// Returns checksum of the BIOS
EXPORT_API uint32_t SWI_GetBiosChecksum(void);
// Struct that holds the input to SWI_BgAffineSet()
typedef struct ALIGNED(4) {
int32_t bgx; // 24.8 fixed point
int32_t bgy; // 24.8 fixed point
int16_t scrx;
int16_t scry;
int16_t scalex; // 8.8 fixed point
int16_t scaley; // 8.8 fixed point
uint32_t angle; // 8.8 fixed point. Low 8 bits ignored.
// The angle is a 32 bit integer (instead of adding a padding field) for
// conveniency. Only bits 8-15 are actually used.
} bg_affine_src;
static_assert(sizeof(bg_affine_src) == 20, "Wrong bg_affine_src size");
// Struct that holds the state of a background affine transformation. It is used
// as container of the output of SWI_BgAffineSet()
typedef struct ALIGNED(4) {
int16_t pa;
int16_t pb;
int16_t pc;
int16_t pd;
int32_t xoff;
int32_t yoff;
} bg_affine_dst;
static_assert(sizeof(bg_affine_dst) == 16, "Wrong bg_affine_dst size");
// This function gets a list of background transformations and outputs the
// correct affine matrices for the GBA hardware.
EXPORT_API
void SWI_BgAffineSet(const bg_affine_src *src, bg_affine_dst *dst,
uint32_t count);
// Struct that holds the input to SWI_ObjAffineSet()
typedef struct ALIGNED(2) {
int16_t sx; // 8.8 fixed point
int16_t sy; // 8.8 fixed point
uint16_t angle; // 8.8 fixed point. Range: 0 - 0xFFFF
uint16_t padding;
} obj_affine_src;
static_assert(sizeof(obj_affine_src) == 8, "Wrong obj_affine_src size");
// This function gets a list of objects transformations and outputs the correct
// affine matrices for the GBA hardware.
EXPORT_API
void SWI_ObjAffineSet(const obj_affine_src *src, void *dst,
uint32_t count, uint32_t increment);
// Struct that holds information used by SWI_BitUnPack()
typedef struct ALIGNED(4) {
int16_t source_length;
uint8_t source_width;
uint8_t dest_width;
uint32_t data_offset;
} bit_unpack_info;
static_assert(sizeof(bit_unpack_info) == 8, "Wrong bit_unpack_info size");
// Used in data_offset in bit_unpack_info.
#define SWI_BITUNPACK_OFFSET_ZERO (1 << 31)
// Unpack data of the specified width in source into the specified width in the
// destination. Used to increase the color depth of images, for example. It
// writes the result to the destination using 32-bit writes. VRAM can be used as
// destination.
EXPORT_API
void SWI_BitUnPack(const void *source, void *dest, const bit_unpack_info *info);
// Values that specify the type of the compression in the 32-bit header of a
// compressed blob. It can be found in bits 4-7 of the header.
#define SWI_UNCOMP_TYPE_LZ77 (1)
#define SWI_UNCOMP_TYPE_HUFFMAN (2)
#define SWI_UNCOMP_TYPE_RL (3)
#define SWI_UNCOMP_TYPE_DIFF (8)
// Value specified in bits 0-3 of the header
#define SWI_DIFF_SIZE_8BIT (1)
#define SWI_DIFF_SIZE_16BIT (2)
// Decompresses LZ77 data from the source and writes the result to the
// destination using 8-bit writes. It can't be used to decompress directly to
// VRAM, as it only accepts 16 and 32-bit accesses.
EXPORT_API
void SWI_LZ77UnCompReadNormalWrite8bit(const void *source, void *dest);
// Decompresses LZ77 data from the source and writes the result to the
// destination using 16-bit writes. VRAM can be used as destination.
EXPORT_API
void SWI_LZ77UnCompReadNormalWrite16bit(const void *source, void *dest);
// Decompresses Huffman-encoded data from the source and writes the result to
// the destination using 32-bit writes. VRAM can be used as destination.
EXPORT_API void SWI_HuffUnComp(const void *source, void *dest);
// Decompresses Run-Length data from the source and writes the result to the
// destination using 8-bit writes. It can't be used to decompress directly to
// VRAM, as it only accepts 16 and 32-bit accesses.
EXPORT_API void SWI_RLUnCompWram(const void *source, void *dest);
// Decompresses Run-Length data from the source and writes the result to the
// destination using 16-bit writes. VRAM can be used as destination.
EXPORT_API void SWI_RLUnCompVram(const void *source, void *dest);
// Convert data in diff format to original data. In this version, data elements
// are 8 bits wide and the result is writen in 8-bit accesses.
EXPORT_API void SWI_Diff8bitUnFilterWram(const void *source, void *dest);
// Convert data in diff format to original data. In this version, data elements
// are 8 bits wide and the result is writen in 16-bit accesses. This means that
// VRAM can be used as destination, as it doesn't accept 8-bit writes.
EXPORT_API void SWI_Diff8bitUnFilterVram(const void *source, void *dest);
// Convert data in diff format to original data. In this version, data elements
// are 16 bits wide and the result is writen in 16-bit accesses.
EXPORT_API void SWI_Diff16bitUnFilter(const void *source, void *dest);
// Set the level of the SOUNDBIAS register by doing small changes. A level of 0
// sets the BIAS level to 0, any other value sets it to 0x200.
EXPORT_API void SWI_SoundBias(uint32_t level);
// Perform a hard reset. Not supported on the SDL2 port.
EXPORT_API NORETURN void SWI_HardReset(void);
#endif // BIOS_H__