Alchemy
Loading...
Searching...
No Matches

irqlock.h

Go to the documentation of this file.
1#ifndef ALCHEMY_IRQLOCK_H
2#define ALCHEMY_IRQLOCK_H
3
4/// @file
5/// Saving, disabling and restoring the interrupt master enable.
6
7#include "io_reg.h"
8#include "types.h"
9
10// The three steps take ime, a pointer to REG_IME. Disabling writes the
11// pointer's low halfword (0x0208, bit 0 clear) back through it. Each step is a
12// do { } while (0) statement macro, the shape the lock sites match through;
13// the two restores' wrappers are devices, since a plain restore matches at
14// some sites. SerialRuntime_Initialize writes IRQ_LOCK out (see its tag).
15
16/// Saves the original IME value in saved.
17#define IME_SAVE(ime, saved) \
18 do { \
19 (saved) = *(ime); \
20 } while (0)
21
22/// Disables interrupts.
23#define IME_DISABLE(ime) \
24 do { \
25 *(ime) = (u16)(u32)(ime); \
26 } while (0)
27
28/// Restores IME from saved.
29/* FAKEMATCH(one-pass): the wrapper; as *(ime) = (saved), 2 and 6 instructions
30 * differ in BattleFx_PlayUnitElementEffect and BattleFx_RunJudgment, all six ☀️
31 * editions. */
32#define IME_RESTORE(ime, saved) \
33 do { \
34 *(ime) = (saved); \
35 } while (0)
36
37/// Disables interrupts and saves IME in saved; IRQ_UNLOCK restores it.
38#define IRQ_LOCK(saved) \
39 do { \
40 volatile u16 *ime_ = &REG_IME; \
41 \
42 IME_SAVE(ime_, saved); \
43 IME_DISABLE(ime_); \
44 } while (0)
45
46/// Restores the IME value saved by IRQ_LOCK.
47/* FAKEMATCH(one-pass): the wrapper keeps the restore apart from the code
48 * before it; as REG_IME = saved, 2 instructions differ in 7 of the 8 locking
49 * Scheduler_ functions in tbs-en. */
50#define IRQ_UNLOCK(saved) \
51 do { \
52 REG_IME = saved; \
53 } while (0)
54
55#endif
The hardware's I/O registers and their bits, as pret names them.
The integer types, TRUE, UNUSED and the fixed-address macros.