Alchemy
Loading...
Searching...
No Matches

io_write_queue.h

Go to the documentation of this file.
1#ifndef ALCHEMY_IO_WRITE_QUEUE_H
2#define ALCHEMY_IO_WRITE_QUEUE_H
3
4/// @file
5/// The register write queue that VBlank carries out after each finished frame.
6
7#include "edition.h"
8#include "irqlock.h"
9#include "types.h"
10
11/// The register writes VBlank carries out once the frame loop has finished a
12/// frame; IoWriteQueue_FlushPending empties it.
14 u16 count; ///< Entries waiting, at most 32.
16 /// Each entry is the value, the address and the control word, in that order.
17 /// A control word with a width (IO_WRITE_8 to IO_WRITE_32) is a register
18 /// write; one without is a DMA, whose three words go to DMA3's source,
19 /// destination and control registers.
20 u32 entries[32][3];
21};
22
23extern struct IoWriteQueue gIoWriteQueue;
24
25// A control word's bits 16 and 17 give a register write's width and bits 18
26// and 19 its operation; Resource_ExecuteTransfer reads them.
27
28/// Writes a byte.
29#define IO_WRITE_8 (1 << 16)
30/// Writes a halfword.
31#define IO_WRITE_16 (2 << 16)
32/// Writes a word.
33#define IO_WRITE_32 (3 << 16)
34/// ORs the value into the register instead of storing it.
35#define IO_WRITE_SET (4 << 16)
36/// Clears the value's bits in the register instead of storing it.
37#define IO_WRITE_CLEAR (8 << 16)
38
39void IoWriteQueue_Store8(u32 address, u32 value);
40void IoWriteQueue_Store16(u32 address, u32 value);
41void IoWriteQueue_Store32(u32 address, u32 value);
42void IoWriteQueue_SetBits8(u32 address, u32 value);
43void IoWriteQueue_SetBits16(u32 address, u32 value);
44void IoWriteQueue_SetBits32(u32 address, u32 value);
45void IoWriteQueue_ClearBits8(u32 address, u32 value);
46void IoWriteQueue_ClearBits16(u32 address, u32 value);
47void IoWriteQueue_ClearBits32(u32 address, u32 value);
48
49/// Disables interrupts to add one register write or DMA to the queue; a write
50/// to a full queue is dropped.
51/// @param control a width (IO_WRITE_8 to IO_WRITE_32), with IO_WRITE_SET or
52/// IO_WRITE_CLEAR to change bits; or a DMA control word.
53// The body is braces alone: as do { } while (0), 8 linked sections of tbs-en
54// differ (the nine writers, six objects with inline pushes and the overlays).
55/* FAKEMATCH(temporary): count_ holds &q->count; as q->count, 15 linked
56 * sections of tbs-en differ (the nine writers, 18 inline pushes, the
57 * overlays). */
58#define IO_WRITE_QUEUE_PUSH(address, value, control) \
59 { \
60 struct IoWriteQueue *q = &gIoWriteQueue; \
61 u32 saved; \
62 s32 count; \
63 u16 *count_ = &q->count; \
64 \
65 IRQ_LOCK(saved); \
66 count = *count_; \
67 if (count <= 31) { \
68 u32 *entry = q->entries[count]; \
69 \
70 *count_ = count + 1; \
71 *entry++ = (value); \
72 *entry++ = (address); \
73 *entry = (control); \
74 } \
75 IRQ_UNLOCK(saved); \
76 }
77
78/// Like IO_WRITE_QUEUE_PUSH, but keeps IME's address in the caller's ime
79/// variable while disabling and restoring interrupts.
80/* FAKEMATCH(temporary): count_ as in IO_WRITE_QUEUE_PUSH; as q->count, its
81 * users BattleFx_PlayUnitElementEffect and BattleFx_RunJudgment differ. */
82#define IO_WRITE_QUEUE_PUSH_IME(ime, address, value, control) \
83 { \
84 struct IoWriteQueue *q; \
85 u32 saved; \
86 s32 count; \
87 u16 *count_; \
88 \
89 q = &gIoWriteQueue; \
90 count_ = &q->count; \
91 IME_SAVE(ime, saved); \
92 IME_DISABLE(ime); \
93 count = *count_; \
94 if (count <= 31) { \
95 u32 *entry = q->entries[count]; \
96 \
97 *count_ = count + 1; \
98 *entry++ = (value); \
99 *entry++ = (address); \
100 *entry = (control); \
101 } \
102 IME_RESTORE(ime, saved); \
103 }
104
105#endif
The edition's language, for C to compare (LANGUAGE == LANGUAGE_GERMAN).
void IoWriteQueue_ClearBits16(u32 address, u32 value)
Queues clearing a halfword register's bits.
Definition io_queue.c:33
void IoWriteQueue_Store32(u32 address, u32 value)
Queues a word store.
Definition io_queue.c:23
void IoWriteQueue_ClearBits8(u32 address, u32 value)
Queues clearing a byte register's bits.
Definition io_queue.c:31
void IoWriteQueue_SetBits32(u32 address, u32 value)
Queues setting a word register's bits.
Definition io_queue.c:29
void IoWriteQueue_SetBits16(u32 address, u32 value)
Queues setting a halfword register's bits.
Definition io_queue.c:27
void IoWriteQueue_SetBits8(u32 address, u32 value)
Queues setting a byte register's bits.
Definition io_queue.c:25
void IoWriteQueue_Store8(u32 address, u32 value)
Queues a byte store.
Definition io_queue.c:19
void IoWriteQueue_ClearBits32(u32 address, u32 value)
Queues clearing a word register's bits.
Definition io_queue.c:35
void IoWriteQueue_Store16(u32 address, u32 value)
Queues a halfword store.
Definition io_queue.c:21
struct IoWriteQueue gIoWriteQueue
Saving, disabling and restoring the interrupt master enable.
The register writes VBlank carries out once the frame loop has finished a frame; IoWriteQueue_FlushPe...
u16 count
Entries waiting, at most 32.
u32 entries[32][3]
Each entry is the value, the address and the control word, in that order.
The integer types, TRUE, UNUSED and the fixed-address macros.
unsigned int u32
Definition types.h:15
unsigned short u16
Definition types.h:13