mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-03-26 12:04:33 -05:00
208 lines
7.7 KiB
C
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__
|