gba_addresses/io.rs
1//! IO Control Registers.
2//!
3//! This region of memory allows you to control the various parts of the GBA.
4//!
5//! Each register has its own unique purpose.
6//! * They are often 16-bits, but not always.
7//! * They are often write-only, though some are read/write, and some are
8//! read-only.
9//! * A the timer addresses do different things between reading and writing.
10//!
11//! Most names here are the same as in [GBATEK][1] with `_ADDR` on the end. Note
12//! that some documents do sometimes use alternate names for some of the IO
13//! registers (particularly the sound registers).
14//!
15//! [1]: https://problemkaputt.de/gbatek.htm#gbaiomap
16//!
17//! * **Wait states:** 0
18//! * **Bus Size:** 32-bit
19//! * **Read/Write:** 8/16/32
20
21/// Display Control
22///
23/// * **Access:** read/write
24/// * **Size:** 2
25pub const DISPCNT_ADDR: usize = 0x0400_0000;
26
27/// Display Status
28///
29/// * **Access:** read/write
30/// * **Size:** 2
31pub const DISPSTAT_ADDR: usize = 0x0400_0004;
32
33/// Vertical Counter
34///
35/// * **Access:** read-only
36/// * **Size:** 1
37pub const VCOUNT_ADDR: usize = 0x0400_0006;
38
39// // // // //
40// BG Control
41// // // // //
42
43/// BG0 Control (video modes 0 or 1)
44///
45/// * **Access:** read/write
46/// * **Size:** 2
47pub const BG0CNT_ADDR: usize = 0x0400_0008;
48
49/// BG1 Control (video modes 0 or 1)
50///
51/// * **Access:** read/write
52/// * **Size:** 2
53pub const BG1CNT_ADDR: usize = 0x0400_000A;
54
55/// BG2 Control (video modes 0, 1, or 2)
56///
57/// * **Access:** read/write
58/// * **Size:** 2
59pub const BG2CNT_ADDR: usize = 0x0400_000C;
60
61/// BG3 Control (video modes 0 or 2)
62///
63/// * **Access:** read/write
64/// * **Size:** 2
65pub const BG3CNT_ADDR: usize = 0x0400_000E;
66
67// // // // //
68// Text Offsets
69// // // // //
70
71/// BG0 Horizontal Offset (video modes 0 or 1)
72///
73/// * **Access:** write-only
74/// * **Size:** 2
75pub const BG0HOFS_ADDR: usize = 0x0400_0010;
76
77/// BG0 Vertical Offset (video modes 0 or 1)
78///
79/// * **Access:** write-only
80/// * **Size:** 2
81pub const BG0VOFS_ADDR: usize = 0x0400_0012;
82
83/// BG1 Horizontal Offset (video modes 0 or 1)
84///
85/// * **Access:** write-only
86/// * **Size:** 2
87pub const BG1HOFS_ADDR: usize = 0x0400_0014;
88
89/// BG1 Vertical Offset (video modes 0 or 1)
90///
91/// * **Access:** write-only
92/// * **Size:** 2
93pub const BG1VOFS_ADDR: usize = 0x0400_0016;
94
95/// BG2 Horizontal Offset (video mode 0)
96///
97/// * **Access:** write-only
98/// * **Size:** 2
99pub const BG2HOFS_ADDR: usize = 0x0400_0018;
100
101/// BG1 Vertical Offset (video mode 0)
102///
103/// * **Access:** write-only
104/// * **Size:** 2
105pub const BG2VOFS_ADDR: usize = 0x0400_001A;
106
107/// BG3 Horizontal Offset (video mode 0)
108///
109/// * **Access:** write-only
110/// * **Size:** 2
111pub const BG3HOFS_ADDR: usize = 0x0400_001C;
112
113/// BG3 Vertical Offset (video mode 0)
114///
115/// * **Access:** write-only
116/// * **Size:** 2
117pub const BG3VOFS_ADDR: usize = 0x0400_001E;
118
119// // // // //
120// Affine Parameters
121// // // // //
122
123/// BG2 Affine Param A (video mode 1 and 2)
124///
125/// * **Access:** write-only
126/// * **Size:** 2
127pub const BG2PA_ADDR: usize = 0x0400_0020;
128
129/// BG2 Affine Param B (video mode 1 and 2)
130///
131/// * **Access:** write-only
132/// * **Size:** 2
133pub const BG2PB_ADDR: usize = 0x0400_0022;
134
135/// BG2 Affine Param C (video mode 1 and 2)
136///
137/// * **Access:** write-only
138/// * **Size:** 2
139pub const BG2PC_ADDR: usize = 0x0400_0024;
140
141/// BG2 Affine Param D (video mode 1 and 2)
142///
143/// * **Access:** write-only
144/// * **Size:** 2
145pub const BG2PD_ADDR: usize = 0x0400_0026;
146
147/// BG2 X reference point (video mode 1, 2, 3, 4, and 5)
148///
149/// * **Access:** write-only
150/// * **Size:** 4
151pub const BG2X_ADDR: usize = 0x0400_0028;
152
153/// BG2 Y reference point (video mode 1, 2, 3, 4, and 5)
154///
155/// * **Access:** write-only
156/// * **Size:** 4
157pub const BG2Y_ADDR: usize = 0x0400_002C;
158
159/// BG3 Affine Param A (video mode 2)
160///
161/// * **Access:** write-only
162/// * **Size:** 2
163pub const BG3PA_ADDR: usize = 0x0400_0030;
164
165/// BG3 Affine Param B (video mode 2)
166///
167/// * **Access:** write-only
168/// * **Size:** 2
169pub const BG3PB_ADDR: usize = 0x0400_0032;
170
171/// BG3 Affine Param C (video mode 2)
172///
173/// * **Access:** write-only
174/// * **Size:** 2
175pub const BG3PC_ADDR: usize = 0x0400_0034;
176
177/// BG3 Affine Param D (video mode 2)
178///
179/// * **Access:** write-only
180/// * **Size:** 2
181pub const BG3PD_ADDR: usize = 0x0400_0036;
182
183/// BG3 X reference point (video mode 2)
184///
185/// * **Access:** write-only
186/// * **Size:** 4
187pub const BG3X_ADDR: usize = 0x0400_0038;
188
189/// BG3 Y reference point (video mode 2)
190///
191/// * **Access:** write-only
192/// * **Size:** 4
193pub const BG3Y_ADDR: usize = 0x0400_003C;
194
195// // // // //
196// Window
197// // // // //
198
199/// Window 0 horizontal.
200///
201/// * **Access:** write-only
202/// * **Size:** 2
203pub const WIN0H_ADDR: usize = 0x0400_0040;
204
205/// Window 1 horizontal.
206///
207/// * **Access:** write-only
208/// * **Size:** 2
209pub const WIN1H_ADDR: usize = 0x0400_0042;
210
211/// Window 0 vertical.
212///
213/// * **Access:** write-only
214/// * **Size:** 2
215pub const WIN0V_ADDR: usize = 0x0400_0044;
216
217/// Window 0 vertical.
218///
219/// * **Access:** write-only
220/// * **Size:** 2
221pub const WIN1V_ADDR: usize = 0x0400_0046;
222
223/// Window 0 inside display.
224///
225/// * **Access:** read/write
226/// * **Size:** 1
227pub const WIN0_IN_ADDR: usize = 0x0400_0048;
228
229/// Window 1 inside display.
230///
231/// * **Access:** read/write
232/// * **Size:** 1
233pub const WIN1_IN_ADDR: usize = 0x0400_0049;
234
235/// Outside window display.
236///
237/// * **Access:** read/write
238/// * **Size:** 1
239pub const WIN_OUT_ADDR: usize = 0x0400_004A;
240
241/// Object window display.
242///
243/// * **Access:** read/write
244/// * **Size:** 1
245pub const OBJ_WIN_ADDR: usize = 0x0400_004B;
246
247// // // // //
248// Special Effects
249// // // // //
250
251/// Mosaic effect size.
252///
253/// * **Access:** write-only
254/// * **Size:** 2
255pub const MOSAIC_ADDR: usize = 0x0400_004C;
256
257/// Color blend special effect.
258///
259/// * **Access:** read/write
260/// * **Size:** 2
261pub const BLDCNT_ADDR: usize = 0x0400_0050;
262
263/// Alpha blend `EVA`.
264///
265/// * **Access:** read/write
266/// * **Size:** 1
267pub const BLDALPHA_A_ADDR: usize = 0x0400_0052;
268
269/// Alpha blend `EVB`.
270///
271/// * **Access:** read/write
272/// * **Size:** 1
273pub const BLDALPHA_B_ADDR: usize = 0x0400_0053;
274
275/// Brightness blend `EVY`.
276///
277/// * **Access:** write-only
278/// * **Size:** 1
279pub const BLDY_ADDR: usize = 0x0400_0054;
280
281// // // // //
282// Sound
283// // // // //
284
285/// Channel 1 Sweep register.
286///
287/// * **Access:** read/write
288/// * **Size:** 1
289pub const CHANNEL1_SWEEP: usize = 0x0400_0060;
290
291/// Channel 1 duty / len / envelope
292///
293/// * **Access:** read/write
294/// * **Size:** 2
295pub const CHANNEL1_DUTY_LEN_ENV: usize = 0x0400_0062;
296
297/// Channel 1 frequency / control
298///
299/// * **Access:** read/write
300/// * **Size:** 2
301pub const CHANNEL1_FREQ_CTRL: usize = 0x0400_0064;
302
303/// Channel 2 duty / len / envelope
304///
305/// * **Access:** read/write
306/// * **Size:** 2
307pub const CHANNEL2_DUTY_LEN_ENV: usize = 0x0400_0068;
308
309/// Channel 2 frequency / control
310///
311/// * **Access:** read/write
312/// * **Size:** 2
313pub const CHANNEL2_FREQ_CTRL: usize = 0x0400_006C;
314
315/// Channel 3 stop / wave RAM select
316///
317/// * **Access:** read/write
318/// * **Size:** 1
319pub const CHANNEL3_SELECT: usize = 0x0400_0070;
320
321/// Channel 3 len
322///
323/// * **Access:** write
324/// * **Size:** 1
325pub const CHANNEL3_LEN: usize = 0x0400_0072;
326
327/// Channel 3 volume
328///
329/// * **Access:** read/write
330/// * **Size:** 1
331pub const CHANNEL3_VOLUME: usize = 0x0400_0073;
332
333/// Channel 3 frequency / control
334///
335/// * **Access:** read/write
336/// * **Size:** 2
337pub const CHANNEL3_FREQ_CTRL: usize = 0x0400_0074;
338
339/// Channel 4 len / envelope
340///
341/// * **Access:** read/write
342/// * **Size:** 2
343pub const CHANNEL4_LEN_ENV: usize = 0x0400_0078;
344
345/// Channel 4 frequency / control
346///
347/// * **Access:** read/write
348/// * **Size:** 2
349pub const CHANNEL4_FREQ_CTRL: usize = 0x0400_007C;
350
351/// Sound Control left/right volume/enable
352///
353/// * **Access:** read/write
354/// * **Size:** 1
355pub const CHANNELS_LEFT_RIGHT_VOLUME: usize = 0x0400_0080;
356
357/// Sound Control left/right volume/enable
358///
359/// * **Access:** read/write
360/// * **Size:** 1
361pub const CHANNELS_LEFT_RIGHT_ENABLED: usize = 0x0400_0081;
362
363/// DMA Sound Control / Mixing
364///
365/// * **Access:** read/write
366/// * **Size:** 2
367pub const DMA_MIXING_CTRL: usize = 0x0400_0082;
368
369/// Sound on/off
370///
371/// * **Access:** read/write
372/// * **Size:** 1
373pub const SOUND_ENABLED_CTRL: usize = 0x0400_0084;
374
375/// Final sound output bias.
376///
377/// * **Access:** read/write
378/// * **Size:** 2
379pub const SOUNDBIAS: usize = 0x0400_0088;
380
381/// Wave RAM data.
382///
383/// This is actually two banks. While you can access one bank here, the other
384/// bank is the sound playing.
385///
386/// When the sound is played, the entire 32-bit region is rotated, 4 bits at a
387/// time, and then the lowest 4 bits are played as that sample.
388///
389/// * **Access:** read/write
390/// * **Size:** 32 (used as 4-bit samples)
391pub const WAVE_RAM_BASE_ADDR: usize = 0x0400_0090;
392
393/// FIFO sound target for sound using DMA 1.
394///
395/// * **Access:** write-only
396/// * **Size:** 4
397pub const FIFO_A_ADDR: usize = 0x0400_00A0;
398
399/// FIFO sound target for sound using DMA 2.
400///
401/// * **Access:** write-only
402/// * **Size:** 4
403pub const FIFO_B_ADDR: usize = 0x0400_00A4;
404
405// // // // //
406// DMA
407// // // // //
408
409/// DMA 0 Source Address
410///
411/// * **Access:** write-only
412/// * **Size:** 4
413pub const DMA0SAD_ADDR: usize = 0x0400_00B0;
414
415/// DMA 0 Destination Address
416///
417/// * **Access:** write-only
418/// * **Size:** 4
419pub const DMA0DAD_ADDR: usize = 0x0400_00B4;
420
421/// DMA 0 transfer count
422///
423/// * **Access:** write-only
424/// * **Size:** 2
425pub const DMA0CNT_L_ADDR: usize = 0x0400_00B8;
426
427/// DMA 0 control bits
428///
429/// * **Access:** read/write
430/// * **Size:** 2
431pub const DMA0CNT_H_ADDR: usize = 0x0400_00BA;
432
433/// DMA 1 Source Address
434///
435/// * **Access:** write-only
436/// * **Size:** 4
437pub const DMA1SAD_ADDR: usize = 0x0400_00BC;
438
439/// DMA 1 Destination Address
440///
441/// * **Access:** write-only
442/// * **Size:** 4
443pub const DMA1DAD_ADDR: usize = 0x0400_00C0;
444
445/// DMA 1 transfer count
446///
447/// * **Access:** write-only
448/// * **Size:** 2
449pub const DMA1CNT_L_ADDR: usize = 0x0400_00C4;
450
451/// DMA 1 control bits
452///
453/// * **Access:** read/write
454/// * **Size:** 2
455pub const DMA1CNT_H_ADDR: usize = 0x0400_00C6;
456
457/// DMA 2 Source Address
458///
459/// * **Access:** write-only
460/// * **Size:** 4
461pub const DMA2SAD_ADDR: usize = 0x0400_00C8;
462
463/// DMA 2 Destination Address
464///
465/// * **Access:** write-only
466/// * **Size:** 4
467pub const DMA2DAD_ADDR: usize = 0x0400_00CC;
468
469/// DMA 2 transfer count
470///
471/// * **Access:** write-only
472/// * **Size:** 2
473pub const DMA2CNT_L_ADDR: usize = 0x0400_00D0;
474
475/// DMA 2 control bits
476///
477/// * **Access:** read/write
478/// * **Size:** 2
479pub const DMA2CNT_H_ADDR: usize = 0x0400_00D2;
480
481/// DMA 3 Source Address
482///
483/// * **Access:** write-only
484/// * **Size:** 4
485pub const DMA3SAD_ADDR: usize = 0x0400_00D4;
486
487/// DMA 3 Destination Address
488///
489/// * **Access:** write-only
490/// * **Size:** 4
491pub const DMA3DAD_ADDR: usize = 0x0400_00D8;
492
493/// DMA 3 transfer count
494///
495/// * **Access:** write-only
496/// * **Size:** 2
497pub const DMA3CNT_L_ADDR: usize = 0x0400_00DC;
498
499/// DMA 3 control bits
500///
501/// * **Access:** read/write
502/// * **Size:** 2
503pub const DMA3CNT_H_ADDR: usize = 0x0400_00DE;
504
505// // // // //
506// Timers
507// // // // //
508
509/// Timer 0 counter / reload
510///
511/// * **Access:** read/write
512/// * **Size:** 2
513pub const TM0CNT_L_ADDR: usize = 0x0400_0100;
514
515/// Timer 0 control bits
516///
517/// * **Access:** read/write
518/// * **Size:** 2
519pub const TM0CNT_H_ADDR: usize = 0x0400_0102;
520
521/// Timer 1 counter / reload
522///
523/// * **Access:** read/write
524/// * **Size:** 2
525pub const TM1CNT_L_ADDR: usize = 0x0400_0104;
526
527/// Timer 1 control bits
528///
529/// * **Access:** read/write
530/// * **Size:** 2
531pub const TM1CNT_H_ADDR: usize = 0x0400_0106;
532
533/// Timer 2 counter / reload
534///
535/// * **Access:** read/write
536/// * **Size:** 2
537pub const TM2CNT_L_ADDR: usize = 0x0400_0108;
538
539/// Timer 2 control bits
540///
541/// * **Access:** read/write
542/// * **Size:** 2
543pub const TM2CNT_H_ADDR: usize = 0x0400_010A;
544
545/// Timer 3 counter / reload
546///
547/// * **Access:** read/write
548/// * **Size:** 2
549pub const TM3CNT_L_ADDR: usize = 0x0400_010C;
550
551/// Timer 3 control bits
552///
553/// * **Access:** read/write
554/// * **Size:** 2
555pub const TM3CNT_H_ADDR: usize = 0x0400_010E;
556
557// // // // //
558// Serial 1
559// // // // //
560
561/// ?
562///
563/// * **Access:** read/write
564/// * **Size:** 4
565pub const SIODATA32_ADDR: usize = 0x0400_0120;
566
567/// ?
568///
569/// * **Access:** read/write
570/// * **Size:** 2
571pub const SIOMULTI0_ADDR: usize = 0x0400_0120;
572
573/// ?
574///
575/// * **Access:** read/write
576/// * **Size:** 2
577pub const SIOMULTI1_ADDR: usize = 0x0400_0122;
578
579/// ?
580///
581/// * **Access:** read/write
582/// * **Size:** 2
583pub const SIOMULTI2_ADDR: usize = 0x0400_0124;
584
585/// ?
586///
587/// * **Access:** read/write
588/// * **Size:** 2
589pub const SIOMULTI3_ADDR: usize = 0x0400_0126;
590
591/// ?
592///
593/// * **Access:** read/write
594/// * **Size:** 2
595pub const SIOCNT_ADDR: usize = 0x0400_0128;
596
597/// ?
598///
599/// * **Access:** read/write
600/// * **Size:** 2
601pub const SIOMLT_SEND_ADDR: usize = 0x0400_012A;
602
603/// ?
604///
605/// * **Access:** read/write
606/// * **Size:** 2
607pub const SIODATA8_ADDR: usize = 0x0400_012A;
608
609// // // // //
610// Keypad
611// // // // //
612
613/// Keys pressed
614///
615/// * 0: A
616/// * 1: B
617/// * 2: Select
618/// * 3: Start
619/// * 4: Right
620/// * 5: Left
621/// * 6: Up
622/// * 7: Down
623/// * 8: R
624/// * 9: L
625///
626/// Bits use a "low active" convention: 0 when pressed, 1 when released.
627///
628/// * **Access:** read-only
629/// * **Size:** 2
630pub const KEYINPUT_ADDR: usize = 0x0400_0130;
631
632/// Keypad interrupt control
633///
634/// Uses the same bit ordering as the [`KEYINPUT_ADDR`](KEYINPUT_ADDR).
635///
636/// * **Access:** read/write
637/// * **Size:** 2
638pub const KEYCNT_ADDR: usize = 0x0400_0132;
639
640// // // // //
641// Serial 2
642// // // // //
643
644/// ?
645///
646/// * **Access:** read/write
647/// * **Size:** 2
648pub const RCNT_ADDR: usize = 0x0400_0134;
649
650/// ?
651///
652/// * **Access:** read/write
653/// * **Size:** 2
654pub const JOYCNT_ADDR: usize = 0x0400_0140;
655
656/// ?
657///
658/// * **Access:** read/write
659/// * **Size:** 4
660pub const JOY_RECV_ADDR: usize = 0x0400_0150;
661
662/// ?
663///
664/// * **Access:** read/write
665/// * **Size:** 4
666pub const JOY_TRANS_ADDR: usize = 0x0400_0154;
667
668/// ?
669///
670/// * **Access:** read/write
671/// * **Size:** 2
672pub const JOYSTAT_ADDR: usize = 0x0400_0158;
673
674// // // // //
675// Interrupt / Waitstate
676// // // // //
677
678/// Interrupt Enable
679///
680/// * 0: Vertical blank
681/// * 1: Horizontal blank
682/// * 2: `VCOUNT` matches `DISPCNT` value.
683/// * 3: Timer 0 Overflow
684/// * 4: Timer 1 Overflow
685/// * 5: Timer 2 Overflow
686/// * 6: Timer 3 Overflow
687/// * 7: Serial Communication
688/// * 8: DMA 0
689/// * 9: DMA 1
690/// * 10: DMA 2
691/// * 11: DMA 3
692/// * 12: Keypad
693///
694/// Controls when the system will *accept* an interrupt from each source. If an
695/// interrupt type isn't set here, then interrupts from that source will be
696/// ignored.
697///
698/// Note that most sources actually *send* an interrupt or not based on their
699/// own control register values elsewhere.
700///
701/// * **Access:** read/write
702/// * **Size:** 2
703pub const IE_ADDR: usize = 0x0400_0200;
704
705/// Interrupt Flags
706///
707/// These bits are set during an interrupt. To acknowledge an interrupt during
708/// the interrupt handler, write a "1" to one or more bits within this register.
709///
710/// Note that if you're acknowledging an interrupt within
711/// `IntrWait`/`VBlankIntrWait` then you must also BIT_OR your changes to the
712/// `IF` address to the
713/// [`IRQ_INTR_WAIT_CHECK_FLAG_ADDR`](IRQ_INTR_WAIT_CHECK_FLAG_ADDR).
714///
715/// * **Access:** read/write
716/// * **Size:** 2
717pub const IF_ADDR: usize = 0x0400_0202;
718
719/// Waitstate Control
720///
721/// * **Access:** read/write
722/// * **Size:** 2
723pub const WAITCNT_ADDR: usize = 0x0400_0204;
724
725/// Interrupt Master Enable
726///
727/// Bit 0 controls if interrupts can happen, all other bits are ignored.
728///
729/// Note that calling `IntrWait` or `VBlankIntrWait` will force bit 0 on.
730///
731/// * **Access:** read/write
732/// * **Size:** 2
733pub const IME_ADDR: usize = 0x0400_0208;