Alchemy
Loading...
Searching...
No Matches

iwram_call.h

Go to the documentation of this file.
1#ifndef ALCHEMY_IWRAM_CALL_H
2#define ALCHEMY_IWRAM_CALL_H
3
4/// @file
5/// The IWRAM call layer: the routines the game keeps resident in IWRAM, each at
6/// its fixed address, and one typed inline per routine that every call goes
7/// through.
8///
9/// It is a habit of the whole game written once: a layer, not a
10/// compiler-steering device (AGENTS.md S2). Code writes `Iwram_Sqrt(value)` or
11/// `Iwram_SignedDivide(dividend, divisor)`, and the inline calls the routine at
12/// its fixed address.
13
14#include "types.h"
15
16// Fixed addresses of IWRAM-resident routines.
17#define Iwram_RatioMulQ14Entry \
18 FIXED_ADDRESS((s32 (*)(s32 divisor, s32 value)), 0x0300013c, IwramRatioMulQ14)
19#define Iwram_ClearWordsEntry \
20 FIXED_ADDRESS((s32 (*)(void *destination, s32 size)), 0x03000164, \
21 IwramClearWords)
22#define Iwram_FillWordsEntry \
23 FIXED_ADDRESS((s32 (*)(void *destination, s32 size, u32 value)), 0x03000168, \
24 IwramFillWords)
25#define Iwram_SqrtEntry \
26 FIXED_ADDRESS((s32 (*)(s32 value)), 0x030001d8, IwramSqrt)
27#define Iwram_ExpandBitRuns \
28 FIXED_ADDRESS((s32 (*)(const void *bits, void *destination, s32 value)), \
29 0x03000214, IwramExpandBitRuns)
30/// Reads all three word-aligned coordinates before writing the result. Input
31/// may be an array or a record's coordinate prefix; output may overlap it.
32#define Iwram_TransformVectorEntry \
33 FIXED_ADDRESS((s32 (*)(const void *vector, s32 *result)), 0x03000250, \
34 IwramTransformVector)
35#define Iwram_TransformMatrixEntry \
36 FIXED_ADDRESS((void (*)(const s32 *matrix)), 0x030002c0, IwramTransformMatrix)
37#define Iwram_SignedDivideEntry \
38 FIXED_ADDRESS((s32 (*)(s32 dividend, s32 divisor)), 0x03000380, \
39 IwramSignedDivide)
40#define Iwram_UnsignedDivideEntry \
41 FIXED_ADDRESS((u32 (*)(u32 dividend, u32 divisor)), 0x030003f0, \
42 IwramUnsignedDivide)
43#define Iwram_DecompressEntry \
44 FIXED_ADDRESS((void *(*)(const void *source, void *destination)), \
45 0x030005c0, IwramDecompress)
46#define Iwram_CopyWordsEntry \
47 FIXED_ADDRESS((s32 (*)(void *destination, const void *source, s32 size)), \
48 0x03001388, IwramCopyWords)
49
50/// All calls go through this layer.
51static inline s32 Iwram_RatioMulQ14(s32 divisor, s32 value) {
52 return Iwram_RatioMulQ14Entry(divisor, value);
53}
54
55static inline s32 Iwram_ClearWords(void *destination, s32 size) {
56 return Iwram_ClearWordsEntry(destination, size);
57}
58
59static inline s32 Iwram_FillWords(void *destination, s32 size, u32 value) {
60 return Iwram_FillWordsEntry(destination, size, value);
61}
62
63static inline s32 Iwram_Sqrt(s32 value) { return Iwram_SqrtEntry(value); }
64
65static inline s32 Iwram_TransformVector(const void *vector, s32 *result) {
66 return Iwram_TransformVectorEntry(vector, result);
67}
68
69static inline void Iwram_TransformMatrix(const s32 *matrix) {
71}
72
73static inline s32 Iwram_SignedDivide(s32 dividend, s32 divisor) {
74 return Iwram_SignedDivideEntry(dividend, divisor);
75}
76
77static inline u32 Iwram_UnsignedDivide(u32 dividend, u32 divisor) {
78 return Iwram_UnsignedDivideEntry(dividend, divisor);
79}
80
81static inline void *Iwram_Decompress(const void *source, void *destination) {
82 return Iwram_DecompressEntry(source, destination);
83}
84
85static inline s32 Iwram_CopyWords(volatile void *destination,
86 const volatile void *source, s32 size) {
87 return Iwram_CopyWordsEntry((void *)destination, (const void *)source, size);
88}
89
90#ifdef MODERN
91/// r0/r1 are the routine's arguments; it returns through ip instead of lr.
93 "a call that returns through ip, which no procedure-call standard produces")
94static inline s32 Iwram_Call2(s32 left, s32 right, void *routine) {
95 s32 result;
96
97 __asm__ volatile("mov r0, %1\n\t"
98 "mov r1, %2\n\t"
99 ".align 2\n\t"
100 "mov ip, pc\n\t"
101 "bx %3\n\t"
102 "mov %0, r0"
103 : "=r"(result)
104 : "r"(left), "r"(right), "r"(routine)
105 : "r0", "r1", "r2", "ip", "cc");
106 return result;
107}
108#else
110 "a call that returns through ip, which no procedure-call standard produces")
111static __inline__ s32 Iwram_Call2(s32 left, s32 right, void *routine) {
112 register s32 result __asm__("r0") = left;
113 register s32 factor __asm__("r1") = right;
114
115 __asm__ volatile(".align 2\n\t"
116 "mov ip, pc\n\t"
117 "bx %2\n\t"
118 : "+r"(result)
119 : "r"(factor), "r"(routine)
120 : "r1", "r2", "ip", "cc");
121 return result;
122}
123#endif
124
125extern u8 IwramMulQ16ReturnIp[];
126
127#define Iwram_MulQ16(left, right) \
128 Iwram_Call2((left), (right), IwramMulQ16ReturnIp)
129
130#define Iwram_CopyWordsOffset FIXED_OFFSET(0x1388, IwramCopyWords, IwramIrqMain)
131#define Iwram_RatioMulQ14Offset \
132 FIXED_OFFSET(0x13c, IwramRatioMulQ14, IwramIrqMain)
133#define Iwram_SqrtOffset FIXED_OFFSET(0x1d8, IwramSqrt, IwramIrqMain)
134
135#endif
#define Iwram_ClearWordsEntry
Definition iwram_call.h:19
static s32 Iwram_RatioMulQ14(s32 divisor, s32 value)
All calls go through this layer.
Definition iwram_call.h:51
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
static s32 Iwram_Sqrt(s32 value)
Definition iwram_call.h:63
#define Iwram_RatioMulQ14Entry
Definition iwram_call.h:17
static __inline__ s32 Iwram_Call2(s32 left, s32 right, void *routine)
Definition iwram_call.h:111
#define Iwram_UnsignedDivideEntry
Definition iwram_call.h:40
static s32 Iwram_FillWords(void *destination, s32 size, u32 value)
Definition iwram_call.h:59
#define Iwram_CopyWordsEntry
Definition iwram_call.h:46
#define Iwram_FillWordsEntry
Definition iwram_call.h:22
static s32 Iwram_SignedDivide(s32 dividend, s32 divisor)
Definition iwram_call.h:73
#define Iwram_TransformVectorEntry
Reads all three word-aligned coordinates before writing the result.
Definition iwram_call.h:32
#define Iwram_SignedDivideEntry
Definition iwram_call.h:37
#define Iwram_TransformMatrixEntry
Definition iwram_call.h:35
#define Iwram_SqrtEntry
Definition iwram_call.h:25
static s32 Iwram_TransformVector(const void *vector, s32 *result)
Definition iwram_call.h:65
#define Iwram_DecompressEntry
Definition iwram_call.h:43
static void * Iwram_Decompress(const void *source, void *destination)
Definition iwram_call.h:81
static u32 Iwram_UnsignedDivide(u32 dividend, u32 divisor)
Definition iwram_call.h:77
u8 IwramMulQ16ReturnIp[]
static s32 Iwram_ClearWords(void *destination, s32 size)
Definition iwram_call.h:55
static void Iwram_TransformMatrix(const s32 *matrix)
Definition iwram_call.h:69
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
unsigned char u8
Definition types.h:11
#define CAMELOT_ASM(proof)
Definition types.h:46