1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
|
#ifndef GUARD_GBA_IO_REG_H
#define GUARD_GBA_IO_REG_H
#define REG_BASE 0x4000000 // I/O register base address
// I/O register offsets
#define REG_OFFSET_DISPCNT 0x0
#define REG_OFFSET_DISPSTAT 0x4
#define REG_OFFSET_VCOUNT 0x6
#define REG_OFFSET_BG0CNT 0x8
#define REG_OFFSET_BG1CNT 0xa
#define REG_OFFSET_BG2CNT 0xc
#define REG_OFFSET_BG3CNT 0xe
#define REG_OFFSET_BG0HOFS 0x10
#define REG_OFFSET_BG0VOFS 0x12
#define REG_OFFSET_BG1HOFS 0x14
#define REG_OFFSET_BG1VOFS 0x16
#define REG_OFFSET_BG2HOFS 0x18
#define REG_OFFSET_BG2VOFS 0x1a
#define REG_OFFSET_BG3HOFS 0x1c
#define REG_OFFSET_BG3VOFS 0x1e
#define REG_OFFSET_BG2PA 0x20
#define REG_OFFSET_BG2PB 0x22
#define REG_OFFSET_BG2PC 0x24
#define REG_OFFSET_BG2PD 0x26
#define REG_OFFSET_BG2X 0x28
#define REG_OFFSET_BG2X_L 0x28
#define REG_OFFSET_BG2X_H 0x2a
#define REG_OFFSET_BG2Y 0x2c
#define REG_OFFSET_BG2Y_L 0x2c
#define REG_OFFSET_BG2Y_H 0x2e
#define REG_OFFSET_BG3PA 0x30
#define REG_OFFSET_BG3PB 0x32
#define REG_OFFSET_BG3PC 0x34
#define REG_OFFSET_BG3PD 0x36
#define REG_OFFSET_BG3X 0x38
#define REG_OFFSET_BG3X_L 0x38
#define REG_OFFSET_BG3X_H 0x3a
#define REG_OFFSET_BG3Y 0x3c
#define REG_OFFSET_BG3Y_L 0x3c
#define REG_OFFSET_BG3Y_H 0x3e
#define REG_OFFSET_WIN0H 0x40
#define REG_OFFSET_WIN1H 0x42
#define REG_OFFSET_WIN0V 0x44
#define REG_OFFSET_WIN1V 0x46
#define REG_OFFSET_WININ 0x48
#define REG_OFFSET_WINOUT 0x4a
#define REG_OFFSET_MOSAIC 0x4c
#define REG_OFFSET_BLDCNT 0x50
#define REG_OFFSET_BLDALPHA 0x52
#define REG_OFFSET_BLDY 0x54
#define REG_OFFSET_SOUND1CNT_L 0x60
#define REG_OFFSET_NR10 0x60
#define REG_OFFSET_SOUND1CNT_H 0x62
#define REG_OFFSET_NR11 0x62
#define REG_OFFSET_NR12 0x63
#define REG_OFFSET_SOUND1CNT_X 0x64
#define REG_OFFSET_NR13 0x64
#define REG_OFFSET_NR14 0x65
#define REG_OFFSET_SOUND2CNT_L 0x68
#define REG_OFFSET_NR21 0x68
#define REG_OFFSET_NR22 0x69
#define REG_OFFSET_SOUND2CNT_H 0x6c
#define REG_OFFSET_NR23 0x6c
#define REG_OFFSET_NR24 0x6d
#define REG_OFFSET_SOUND3CNT_L 0x70
#define REG_OFFSET_NR30 0x70
#define REG_OFFSET_SOUND3CNT_H 0x72
#define REG_OFFSET_NR31 0x72
#define REG_OFFSET_NR32 0x73
#define REG_OFFSET_SOUND3CNT_X 0x74
#define REG_OFFSET_NR33 0x74
#define REG_OFFSET_NR34 0x75
#define REG_OFFSET_SOUND4CNT_L 0x78
#define REG_OFFSET_NR41 0x78
#define REG_OFFSET_NR42 0x79
#define REG_OFFSET_SOUND4CNT_H 0x7c
#define REG_OFFSET_NR43 0x7c
#define REG_OFFSET_NR44 0x7d
#define REG_OFFSET_SOUNDCNT_L 0x80
#define REG_OFFSET_NR50 0x80
#define REG_OFFSET_NR51 0x81
#define REG_OFFSET_SOUNDCNT_H 0x82
#define REG_OFFSET_SOUNDCNT_X 0x84
#define REG_OFFSET_NR52 0x84
#define REG_OFFSET_SOUNDBIAS 0x88
#define REG_OFFSET_SOUNDBIAS_L 0x88
#define REG_OFFSET_SOUNDBIAS_H 0x89
#define REG_OFFSET_WAVE_RAM0 0x90
#define REG_OFFSET_WAVE_RAM1 0x94
#define REG_OFFSET_WAVE_RAM2 0x98
#define REG_OFFSET_WAVE_RAM3 0x9c
#define REG_OFFSET_FIFO_A 0xa0
#define REG_OFFSET_FIFO_B 0xa4
#define REG_OFFSET_DMA0 0xb0
#define REG_OFFSET_DMA0SAD 0xb0
#define REG_OFFSET_DMA0SAD_L 0xb0
#define REG_OFFSET_DMA0SAD_H 0xb2
#define REG_OFFSET_DMA0DAD 0xb4
#define REG_OFFSET_DMA0DAD_L 0xb4
#define REG_OFFSET_DMA0DAD_H 0xb6
#define REG_OFFSET_DMA0CNT 0xb8
#define REG_OFFSET_DMA0CNT_L 0xb8
#define REG_OFFSET_DMA0CNT_H 0xba
#define REG_OFFSET_DMA1 0xbc
#define REG_OFFSET_DMA1SAD 0xbc
#define REG_OFFSET_DMA1SAD_L 0xbc
#define REG_OFFSET_DMA1SAD_H 0xbe
#define REG_OFFSET_DMA1DAD 0xc0
#define REG_OFFSET_DMA1DAD_L 0xc0
#define REG_OFFSET_DMA1DAD_H 0xc2
#define REG_OFFSET_DMA1CNT 0xc4
#define REG_OFFSET_DMA1CNT_L 0xc4
#define REG_OFFSET_DMA1CNT_H 0xc6
#define REG_OFFSET_DMA2 0xc8
#define REG_OFFSET_DMA2SAD 0xc8
#define REG_OFFSET_DMA2SAD_L 0xc8
#define REG_OFFSET_DMA2SAD_H 0xca
#define REG_OFFSET_DMA2DAD 0xcc
#define REG_OFFSET_DMA2DAD_L 0xcc
#define REG_OFFSET_DMA2DAD_H 0xce
#define REG_OFFSET_DMA2CNT 0xd0
#define REG_OFFSET_DMA2CNT_L 0xd0
#define REG_OFFSET_DMA2CNT_H 0xd2
#define REG_OFFSET_DMA3 0xd4
#define REG_OFFSET_DMA3SAD 0xd4
#define REG_OFFSET_DMA3SAD_L 0xd4
#define REG_OFFSET_DMA3SAD_H 0xd6
#define REG_OFFSET_DMA3DAD 0xd8
#define REG_OFFSET_DMA3DAD_L 0xd8
#define REG_OFFSET_DMA3DAD_H 0xda
#define REG_OFFSET_DMA3CNT 0xdc
#define REG_OFFSET_DMA3CNT_L 0xdc
#define REG_OFFSET_DMA3CNT_H 0xde
#define REG_OFFSET_TMCNT 0x100
#define REG_OFFSET_TMCNT_L 0x100
#define REG_OFFSET_TMCNT_H 0x102
#define REG_OFFSET_TM0CNT 0x100
#define REG_OFFSET_TM0CNT_L 0x100
#define REG_OFFSET_TM0CNT_H 0x102
#define REG_OFFSET_TM1CNT 0x104
#define REG_OFFSET_TM1CNT_L 0x104
#define REG_OFFSET_TM1CNT_H 0x106
#define REG_OFFSET_TM2CNT 0x108
#define REG_OFFSET_TM2CNT_L 0x108
#define REG_OFFSET_TM2CNT_H 0x10a
#define REG_OFFSET_TM3CNT 0x10c
#define REG_OFFSET_TM3CNT_L 0x10c
#define REG_OFFSET_TM3CNT_H 0x10e
#define REG_OFFSET_SIOCNT 0x128
#define REG_OFFSET_SIODATA8 0x12a
#define REG_OFFSET_SIODATA32 0x120
#define REG_OFFSET_SIOMLT_SEND 0x12a
#define REG_OFFSET_SIOMLT_RECV 0x120
#define REG_OFFSET_SIOMULTI0 0x120
#define REG_OFFSET_SIOMULTI1 0x122
#define REG_OFFSET_SIOMULTI2 0x124
#define REG_OFFSET_SIOMULTI3 0x126
#define REG_OFFSET_KEYINPUT 0x130
#define REG_OFFSET_KEYCNT 0x132
#define REG_OFFSET_RCNT 0x134
#define REG_OFFSET_JOYCNT 0x140
#define REG_OFFSET_JOYSTAT 0x158
#define REG_OFFSET_JOY_RECV 0x150
#define REG_OFFSET_JOY_RECV_L 0x150
#define REG_OFFSET_JOY_RECV_H 0x152
#define REG_OFFSET_JOY_TRANS 0x154
#define REG_OFFSET_JOY_TRANS_L 0x154
#define REG_OFFSET_JOY_TRANS_H 0x156
#define REG_OFFSET_IME 0x208
#define REG_OFFSET_IE 0x200
#define REG_OFFSET_IF 0x202
#define REG_OFFSET_WAITCNT 0x204
// I/O register addresses
#define REG_ADDR_DISPCNT (REG_BASE + REG_OFFSET_DISPCNT)
#define REG_ADDR_DISPSTAT (REG_BASE + REG_OFFSET_DISPSTAT)
#define REG_ADDR_VCOUNT (REG_BASE + REG_OFFSET_VCOUNT)
#define REG_ADDR_BG0CNT (REG_BASE + REG_OFFSET_BG0CNT)
#define REG_ADDR_BG1CNT (REG_BASE + REG_OFFSET_BG1CNT)
#define REG_ADDR_BG2CNT (REG_BASE + REG_OFFSET_BG2CNT)
#define REG_ADDR_BG3CNT (REG_BASE + REG_OFFSET_BG3CNT)
#define REG_ADDR_BG0HOFS (REG_BASE + REG_OFFSET_BG0HOFS)
#define REG_ADDR_BG0VOFS (REG_BASE + REG_OFFSET_BG0VOFS)
#define REG_ADDR_BG1HOFS (REG_BASE + REG_OFFSET_BG1HOFS)
#define REG_ADDR_BG1VOFS (REG_BASE + REG_OFFSET_BG1VOFS)
#define REG_ADDR_BG2HOFS (REG_BASE + REG_OFFSET_BG2HOFS)
#define REG_ADDR_BG2VOFS (REG_BASE + REG_OFFSET_BG2VOFS)
#define REG_ADDR_BG3HOFS (REG_BASE + REG_OFFSET_BG3HOFS)
#define REG_ADDR_BG3VOFS (REG_BASE + REG_OFFSET_BG3VOFS)
#define REG_ADDR_BG2PA (REG_BASE + REG_OFFSET_BG2PA)
#define REG_ADDR_BG2PB (REG_BASE + REG_OFFSET_BG2PB)
#define REG_ADDR_BG2PC (REG_BASE + REG_OFFSET_BG2PC)
#define REG_ADDR_BG2PD (REG_BASE + REG_OFFSET_BG2PD)
#define REG_ADDR_BG2X (REG_BASE + REG_OFFSET_BG2X)
#define REG_ADDR_BG2X_L (REG_BASE + REG_OFFSET_BG2X_L)
#define REG_ADDR_BG2X_H (REG_BASE + REG_OFFSET_BG2X_H)
#define REG_ADDR_BG2Y (REG_BASE + REG_OFFSET_BG2Y)
#define REG_ADDR_BG2Y_L (REG_BASE + REG_OFFSET_BG2Y_L)
#define REG_ADDR_BG2Y_H (REG_BASE + REG_OFFSET_BG2Y_H)
#define REG_ADDR_BG3PA (REG_BASE + REG_OFFSET_BG3PA)
#define REG_ADDR_BG3PB (REG_BASE + REG_OFFSET_BG3PB)
#define REG_ADDR_BG3PC (REG_BASE + REG_OFFSET_BG3PC)
#define REG_ADDR_BG3PD (REG_BASE + REG_OFFSET_BG3PD)
#define REG_ADDR_BG3X (REG_BASE + REG_OFFSET_BG3X)
#define REG_ADDR_BG3X_L (REG_BASE + REG_OFFSET_BG3X_L)
#define REG_ADDR_BG3X_H (REG_BASE + REG_OFFSET_BG3X_H)
#define REG_ADDR_BG3Y (REG_BASE + REG_OFFSET_BG3Y)
#define REG_ADDR_BG3Y_L (REG_BASE + REG_OFFSET_BG3Y_L)
#define REG_ADDR_BG3Y_H (REG_BASE + REG_OFFSET_BG3Y_H)
#define REG_ADDR_WIN0H (REG_BASE + REG_OFFSET_WIN0H)
#define REG_ADDR_WIN1H (REG_BASE + REG_OFFSET_WIN1H)
#define REG_ADDR_WIN0V (REG_BASE + REG_OFFSET_WIN0V)
#define REG_ADDR_WIN1V (REG_BASE + REG_OFFSET_WIN1V)
#define REG_ADDR_WININ (REG_BASE + REG_OFFSET_WININ)
#define REG_ADDR_WINOUT (REG_BASE + REG_OFFSET_WINOUT)
#define REG_ADDR_MOSAIC (REG_BASE + REG_OFFSET_MOSAIC)
#define REG_ADDR_BLDCNT (REG_BASE + REG_OFFSET_BLDCNT)
#define REG_ADDR_BLDALPHA (REG_BASE + REG_OFFSET_BLDALPHA)
#define REG_ADDR_BLDY (REG_BASE + REG_OFFSET_BLDY)
#define REG_ADDR_SOUND1CNT_L (REG_BASE + REG_OFFSET_SOUND1CNT_L)
#define REG_ADDR_NR10 (REG_BASE + REG_OFFSET_NR10)
#define REG_ADDR_SOUND1CNT_H (REG_BASE + REG_OFFSET_SOUND1CNT_H)
#define REG_ADDR_NR11 (REG_BASE + REG_OFFSET_NR11)
#define REG_ADDR_NR12 (REG_BASE + REG_OFFSET_NR12)
#define REG_ADDR_SOUND1CNT_X (REG_BASE + REG_OFFSET_SOUND1CNT_X)
#define REG_ADDR_NR13 (REG_BASE + REG_OFFSET_NR13)
#define REG_ADDR_NR14 (REG_BASE + REG_OFFSET_NR14)
#define REG_ADDR_SOUND2CNT_L (REG_BASE + REG_OFFSET_SOUND2CNT_L)
#define REG_ADDR_NR21 (REG_BASE + REG_OFFSET_NR21)
#define REG_ADDR_NR22 (REG_BASE + REG_OFFSET_NR22)
#define REG_ADDR_SOUND2CNT_H (REG_BASE + REG_OFFSET_SOUND2CNT_H)
#define REG_ADDR_NR23 (REG_BASE + REG_OFFSET_NR23)
#define REG_ADDR_NR24 (REG_BASE + REG_OFFSET_NR24)
#define REG_ADDR_SOUND3CNT_L (REG_BASE + REG_OFFSET_SOUND3CNT_L)
#define REG_ADDR_NR30 (REG_BASE + REG_OFFSET_NR30)
#define REG_ADDR_SOUND3CNT_H (REG_BASE + REG_OFFSET_SOUND3CNT_H)
#define REG_ADDR_NR31 (REG_BASE + REG_OFFSET_NR31)
#define REG_ADDR_NR32 (REG_BASE + REG_OFFSET_NR32)
#define REG_ADDR_SOUND3CNT_X (REG_BASE + REG_OFFSET_SOUND3CNT_X)
#define REG_ADDR_NR33 (REG_BASE + REG_OFFSET_NR33)
#define REG_ADDR_NR34 (REG_BASE + REG_OFFSET_NR34)
#define REG_ADDR_SOUND4CNT_L (REG_BASE + REG_OFFSET_SOUND4CNT_L)
#define REG_ADDR_NR41 (REG_BASE + REG_OFFSET_NR41)
#define REG_ADDR_NR42 (REG_BASE + REG_OFFSET_NR42)
#define REG_ADDR_SOUND4CNT_H (REG_BASE + REG_OFFSET_SOUND4CNT_H)
#define REG_ADDR_NR43 (REG_BASE + REG_OFFSET_NR43)
#define REG_ADDR_NR44 (REG_BASE + REG_OFFSET_NR44)
#define REG_ADDR_SOUNDCNT_L (REG_BASE + REG_OFFSET_SOUNDCNT_L)
#define REG_ADDR_NR50 (REG_BASE + REG_OFFSET_NR50)
#define REG_ADDR_NR51 (REG_BASE + REG_OFFSET_NR51)
#define REG_ADDR_SOUNDCNT_H (REG_BASE + REG_OFFSET_SOUNDCNT_H)
#define REG_ADDR_SOUNDCNT_X (REG_BASE + REG_OFFSET_SOUNDCNT_X)
#define REG_ADDR_NR52 (REG_BASE + REG_OFFSET_NR52)
#define REG_ADDR_SOUNDBIAS (REG_BASE + REG_OFFSET_SOUNDBIAS)
#define REG_ADDR_SOUNDBIAS_L (REG_BASE + REG_OFFSET_SOUNDBIAS_L)
#define REG_ADDR_SOUNDBIAS_H (REG_BASE + REG_OFFSET_SOUNDBIAS_H)
#define REG_ADDR_WAVE_RAM0 (REG_BASE + REG_OFFSET_WAVE_RAM0)
#define REG_ADDR_WAVE_RAM1 (REG_BASE + REG_OFFSET_WAVE_RAM1)
#define REG_ADDR_WAVE_RAM2 (REG_BASE + REG_OFFSET_WAVE_RAM2)
#define REG_ADDR_WAVE_RAM3 (REG_BASE + REG_OFFSET_WAVE_RAM3)
#define REG_ADDR_FIFO_A (REG_BASE + REG_OFFSET_FIFO_A)
#define REG_ADDR_FIFO_B (REG_BASE + REG_OFFSET_FIFO_B)
#define REG_ADDR_DMA0 (REG_BASE + REG_OFFSET_DMA0)
#define REG_ADDR_DMA0SAD (REG_BASE + REG_OFFSET_DMA0SAD)
#define REG_ADDR_DMA0DAD (REG_BASE + REG_OFFSET_DMA0DAD)
#define REG_ADDR_DMA0CNT (REG_BASE + REG_OFFSET_DMA0CNT)
#define REG_ADDR_DMA0CNT_L (REG_BASE + REG_OFFSET_DMA0CNT_L)
#define REG_ADDR_DMA0CNT_H (REG_BASE + REG_OFFSET_DMA0CNT_H)
#define REG_ADDR_DMA1 (REG_BASE + REG_OFFSET_DMA1)
#define REG_ADDR_DMA1SAD (REG_BASE + REG_OFFSET_DMA1SAD)
#define REG_ADDR_DMA1DAD (REG_BASE + REG_OFFSET_DMA1DAD)
#define REG_ADDR_DMA1CNT (REG_BASE + REG_OFFSET_DMA1CNT)
#define REG_ADDR_DMA1CNT_L (REG_BASE + REG_OFFSET_DMA1CNT_L)
#define REG_ADDR_DMA1CNT_H (REG_BASE + REG_OFFSET_DMA1CNT_H)
#define REG_ADDR_DMA2 (REG_BASE + REG_OFFSET_DMA2)
#define REG_ADDR_DMA2SAD (REG_BASE + REG_OFFSET_DMA2SAD)
#define REG_ADDR_DMA2DAD (REG_BASE + REG_OFFSET_DMA2DAD)
#define REG_ADDR_DMA2CNT (REG_BASE + REG_OFFSET_DMA2CNT)
#define REG_ADDR_DMA2CNT_L (REG_BASE + REG_OFFSET_DMA2CNT_L)
#define REG_ADDR_DMA2CNT_H (REG_BASE + REG_OFFSET_DMA2CNT_H)
#define REG_ADDR_DMA3 (REG_BASE + REG_OFFSET_DMA3)
#define REG_ADDR_DMA3SAD (REG_BASE + REG_OFFSET_DMA3SAD)
#define REG_ADDR_DMA3DAD (REG_BASE + REG_OFFSET_DMA3DAD)
#define REG_ADDR_DMA3CNT (REG_BASE + REG_OFFSET_DMA3CNT)
#define REG_ADDR_DMA3CNT_L (REG_BASE + REG_OFFSET_DMA3CNT_L)
#define REG_ADDR_DMA3CNT_H (REG_BASE + REG_OFFSET_DMA3CNT_H)
#define REG_ADDR_TMCNT (REG_BASE + REG_OFFSET_TMCNT)
#define REG_ADDR_TMCNT_L (REG_BASE + REG_OFFSET_TMCNT_L)
#define REG_ADDR_TMCNT_H (REG_BASE + REG_OFFSET_TMCNT_H)
#define REG_ADDR_TM0CNT (REG_BASE + REG_OFFSET_TM0CNT)
#define REG_ADDR_TM0CNT_L (REG_BASE + REG_OFFSET_TM0CNT_L)
#define REG_ADDR_TM0CNT_H (REG_BASE + REG_OFFSET_TM0CNT_H)
#define REG_ADDR_TM1CNT (REG_BASE + REG_OFFSET_TM1CNT)
#define REG_ADDR_TM1CNT_L (REG_BASE + REG_OFFSET_TM1CNT_L)
#define REG_ADDR_TM1CNT_H (REG_BASE + REG_OFFSET_TM1CNT_H)
#define REG_ADDR_TM2CNT (REG_BASE + REG_OFFSET_TM2CNT)
#define REG_ADDR_TM2CNT_L (REG_BASE + REG_OFFSET_TM2CNT_L)
#define REG_ADDR_TM2CNT_H (REG_BASE + REG_OFFSET_TM2CNT_H)
#define REG_ADDR_TM3CNT (REG_BASE + REG_OFFSET_TM3CNT)
#define REG_ADDR_TM3CNT_L (REG_BASE + REG_OFFSET_TM3CNT_L)
#define REG_ADDR_TM3CNT_H (REG_BASE + REG_OFFSET_TM3CNT_H)
#define REG_ADDR_SIOCNT (REG_BASE + REG_OFFSET_SIOCNT)
#define REG_ADDR_SIODATA8 (REG_BASE + REG_OFFSET_SIODATA8)
#define REG_ADDR_SIODATA32 (REG_BASE + REG_OFFSET_SIODATA32)
#define REG_ADDR_SIOMLT_SEND (REG_BASE + REG_OFFSET_SIOMLT_SEND)
#define REG_ADDR_SIOMLT_RECV (REG_BASE + REG_OFFSET_SIOMLT_RECV)
#define REG_ADDR_SIOMULTI0 (REG_BASE + REG_OFFSET_SIOMULTI0)
#define REG_ADDR_SIOMULTI1 (REG_BASE + REG_OFFSET_SIOMULTI1)
#define REG_ADDR_SIOMULTI2 (REG_BASE + REG_OFFSET_SIOMULTI2)
#define REG_ADDR_SIOMULTI3 (REG_BASE + REG_OFFSET_SIOMULTI3)
#define REG_ADDR_KEYINPUT (REG_BASE + REG_OFFSET_KEYINPUT)
#define REG_ADDR_KEYCNT (REG_BASE + REG_OFFSET_KEYCNT)
#define REG_ADDR_RCNT (REG_BASE + REG_OFFSET_RCNT)
#define REG_ADDR_JOYCNT (REG_BASE + REG_OFFSET_JOYCNT)
#define REG_ADDR_JOYSTAT (REG_BASE + REG_OFFSET_JOYSTAT)
#define REG_ADDR_JOY_RECV (REG_BASE + REG_OFFSET_JOY_RECV)
#define REG_ADDR_JOY_RECV_L (REG_BASE + REG_OFFSET_JOY_RECV_L)
#define REG_ADDR_JOY_RECV_H (REG_BASE + REG_OFFSET_JOY_RECV_H)
#define REG_ADDR_JOY_TRANS (REG_BASE + REG_OFFSET_JOY_TRANS)
#define REG_ADDR_JOY_TRANS_L (REG_BASE + REG_OFFSET_JOY_TRANS_L)
#define REG_ADDR_JOY_TRANS_H (REG_BASE + REG_OFFSET_JOY_TRANS_H)
#define REG_ADDR_IME (REG_BASE + REG_OFFSET_IME)
#define REG_ADDR_IE (REG_BASE + REG_OFFSET_IE)
#define REG_ADDR_IF (REG_BASE + REG_OFFSET_IF)
#define REG_ADDR_WAITCNT (REG_BASE + REG_OFFSET_WAITCNT)
// I/O registers
#define REG_DISPCNT (*(vu16 *)REG_ADDR_DISPCNT)
#define REG_DISPSTAT (*(vu16 *)REG_ADDR_DISPSTAT)
#define REG_VCOUNT (*(vu16 *)REG_ADDR_VCOUNT)
#define REG_BG0CNT (*(vu16 *)REG_ADDR_BG0CNT)
#define REG_BG1CNT (*(vu16 *)REG_ADDR_BG1CNT)
#define REG_BG2CNT (*(vu16 *)REG_ADDR_BG2CNT)
#define REG_BG3CNT (*(vu16 *)REG_ADDR_BG3CNT)
#define REG_BG0HOFS (*(vu16 *)REG_ADDR_BG0HOFS)
#define REG_BG0VOFS (*(vu16 *)REG_ADDR_BG0VOFS)
#define REG_BG1HOFS (*(vu16 *)REG_ADDR_BG1HOFS)
#define REG_BG1VOFS (*(vu16 *)REG_ADDR_BG1VOFS)
#define REG_BG2HOFS (*(vu16 *)REG_ADDR_BG2HOFS)
#define REG_BG2VOFS (*(vu16 *)REG_ADDR_BG2VOFS)
#define REG_BG3HOFS (*(vu16 *)REG_ADDR_BG3HOFS)
#define REG_BG3VOFS (*(vu16 *)REG_ADDR_BG3VOFS)
#define REG_BG2PA (*(vu16 *)REG_ADDR_BG2PA)
#define REG_BG2PB (*(vu16 *)REG_ADDR_BG2PB)
#define REG_BG2PC (*(vu16 *)REG_ADDR_BG2PC)
#define REG_BG2PD (*(vu16 *)REG_ADDR_BG2PD)
#define REG_BG2X (*(vu32 *)REG_ADDR_BG2X)
#define REG_BG2X_L (*(vu16 *)REG_ADDR_BG2X_L)
#define REG_BG2X_H (*(vu16 *)REG_ADDR_BG2X_H)
#define REG_BG2Y (*(vu32 *)REG_ADDR_BG2Y)
#define REG_BG2Y_L (*(vu16 *)REG_ADDR_BG2Y_L)
#define REG_BG2Y_H (*(vu16 *)REG_ADDR_BG2Y_H)
#define REG_BG3PA (*(vu16 *)REG_ADDR_BG3PA)
#define REG_BG3PB (*(vu16 *)REG_ADDR_BG3PB)
#define REG_BG3PC (*(vu16 *)REG_ADDR_BG3PC)
#define REG_BG3PD (*(vu16 *)REG_ADDR_BG3PD)
#define REG_BG3X (*(vu32 *)REG_ADDR_BG3X)
#define REG_BG3X_L (*(vu16 *)REG_ADDR_BG3X_L)
#define REG_BG3X_H (*(vu16 *)REG_ADDR_BG3X_H)
#define REG_BG3Y (*(vu32 *)REG_ADDR_BG3Y)
#define REG_BG3Y_L (*(vu16 *)REG_ADDR_BG3Y_L)
#define REG_BG3Y_H (*(vu16 *)REG_ADDR_BG3Y_H)
#define REG_WIN0H (*(vu16 *)REG_ADDR_WIN0H)
#define REG_WIN1H (*(vu16 *)REG_ADDR_WIN1H)
#define REG_WIN0V (*(vu16 *)REG_ADDR_WIN0V)
#define REG_WIN1V (*(vu16 *)REG_ADDR_WIN1V)
#define REG_WININ (*(vu16 *)REG_ADDR_WININ)
#define REG_WINOUT (*(vu16 *)REG_ADDR_WINOUT)
#define REG_MOSAIC (*(vu16 *)REG_ADDR_MOSAIC)
#define REG_BLDCNT (*(vu16 *)REG_ADDR_BLDCNT)
#define REG_BLDALPHA (*(vu16 *)REG_ADDR_BLDALPHA)
#define REG_BLDY (*(vu16 *)REG_ADDR_BLDY)
#define REG_SOUND1CNT_L (*(vu16 *)REG_ADDR_SOUND1CNT_L)
#define REG_NR10 (*(vu8 *)REG_ADDR_NR10)
#define REG_SOUND1CNT_H (*(vu16 *)REG_ADDR_SOUND1CNT_H)
#define REG_NR11 (*(vu8 *)REG_ADDR_NR11)
#define REG_NR12 (*(vu8 *)REG_ADDR_NR12)
#define REG_SOUND1CNT_X (*(vu16 *)REG_ADDR_SOUND1CNT_X)
#define REG_NR13 (*(vu8 *)REG_ADDR_NR13)
#define REG_NR14 (*(vu8 *)REG_ADDR_NR14)
#define REG_SOUND2CNT_L (*(vu16 *)REG_ADDR_SOUND2CNT_L)
#define REG_NR21 (*(vu8 *)REG_ADDR_NR21)
#define REG_NR22 (*(vu8 *)REG_ADDR_NR22)
#define REG_SOUND2CNT_H (*(vu16 *)REG_ADDR_SOUND2CNT_H)
#define REG_NR23 (*(vu8 *)REG_ADDR_NR23)
#define REG_NR24 (*(vu8 *)REG_ADDR_NR24)
#define REG_SOUND3CNT_L (*(vu16 *)REG_ADDR_SOUND3CNT_L)
#define REG_NR30 (*(vu8 *)REG_ADDR_NR30)
#define REG_SOUND3CNT_H (*(vu16 *)REG_ADDR_SOUND3CNT_H)
#define REG_NR31 (*(vu8 *)REG_ADDR_NR31)
#define REG_NR32 (*(vu8 *)REG_ADDR_NR32)
#define REG_SOUND3CNT_X (*(vu16 *)REG_ADDR_SOUND3CNT_X)
#define REG_NR33 (*(vu8 *)REG_ADDR_NR33)
#define REG_NR34 (*(vu8 *)REG_ADDR_NR34)
#define REG_SOUND4CNT_L (*(vu16 *)REG_ADDR_SOUND4CNT_L)
#define REG_NR41 (*(vu8 *)REG_ADDR_NR41)
#define REG_NR42 (*(vu8 *)REG_ADDR_NR42)
#define REG_SOUND4CNT_H (*(vu16 *)REG_ADDR_SOUND4CNT_H)
#define REG_NR43 (*(vu8 *)REG_ADDR_NR43)
#define REG_NR44 (*(vu8 *)REG_ADDR_NR44)
#define REG_SOUNDCNT_L (*(vu16 *)REG_ADDR_SOUNDCNT_L)
#define REG_NR50 (*(vu8 *)REG_ADDR_NR50)
#define REG_NR51 (*(vu8 *)REG_ADDR_NR51)
#define REG_SOUNDCNT_H (*(vu16 *)REG_ADDR_SOUNDCNT_H)
#define REG_SOUNDCNT_X (*(vu16 *)REG_ADDR_SOUNDCNT_X)
#define REG_NR52 (*(vu8 *)REG_ADDR_NR52)
#define REG_SOUNDBIAS (*(vu16 *)REG_ADDR_SOUNDBIAS)
#define REG_SOUNDBIAS_L (*(vu8 *)REG_ADDR_SOUNDBIAS_L)
#define REG_SOUNDBIAS_H (*(vu8 *)REG_ADDR_SOUNDBIAS_H)
#define REG_WAVE_RAM0 (*(vu32 *)REG_ADDR_WAVE_RAM0)
#define REG_WAVE_RAM1 (*(vu32 *)REG_ADDR_WAVE_RAM1)
#define REG_WAVE_RAM2 (*(vu32 *)REG_ADDR_WAVE_RAM2)
#define REG_WAVE_RAM3 (*(vu32 *)REG_ADDR_WAVE_RAM3)
#define REG_FIFO_A (*(vu32 *)REG_ADDR_FIFO_A)
#define REG_FIFO_B (*(vu32 *)REG_ADDR_FIFO_B)
#define REG_DMA0SAD (*(vu32 *)REG_ADDR_DMA0SAD)
#define REG_DMA0DAD (*(vu32 *)REG_ADDR_DMA0DAD)
#define REG_DMA0CNT (*(vu32 *)REG_ADDR_DMA0CNT)
#define REG_DMA0CNT_L (*(vu16 *)REG_ADDR_DMA0CNT_L)
#define REG_DMA0CNT_H (*(vu16 *)REG_ADDR_DMA0CNT_H)
#define REG_DMA1SAD (*(vu32 *)REG_ADDR_DMA1SAD)
#define REG_DMA1DAD (*(vu32 *)REG_ADDR_DMA1DAD)
#define REG_DMA1CNT (*(vu32 *)REG_ADDR_DMA1CNT)
#define REG_DMA1CNT_L (*(vu16 *)REG_ADDR_DMA1CNT_L)
#define REG_DMA1CNT_H (*(vu16 *)REG_ADDR_DMA1CNT_H)
#define REG_DMA2SAD (*(vu32 *)REG_ADDR_DMA2SAD)
#define REG_DMA2DAD (*(vu32 *)REG_ADDR_DMA2DAD)
#define REG_DMA2CNT (*(vu32 *)REG_ADDR_DMA2CNT)
#define REG_DMA2CNT_L (*(vu16 *)REG_ADDR_DMA2CNT_L)
#define REG_DMA2CNT_H (*(vu16 *)REG_ADDR_DMA2CNT_H)
#define REG_DMA3SAD (*(vu32 *)REG_ADDR_DMA3SAD)
#define REG_DMA3DAD (*(vu32 *)REG_ADDR_DMA3DAD)
#define REG_DMA3CNT (*(vu32 *)REG_ADDR_DMA3CNT)
#define REG_DMA3CNT_L (*(vu16 *)REG_ADDR_DMA3CNT_L)
#define REG_DMA3CNT_H (*(vu16 *)REG_ADDR_DMA3CNT_H)
#define REG_TMCNT(n) (*(vu16 *)(REG_ADDR_TMCNT + ((n) * 4)))
#define REG_TMCNT_L(n) (*(vu16 *)(REG_ADDR_TMCNT_L + ((n) * 4)))
#define REG_TMCNT_H(n) (*(vu16 *)(REG_ADDR_TMCNT_H + ((n) * 4)))
#define REG_TM0CNT (*(vu32 *)REG_ADDR_TM0CNT)
#define REG_TM0CNT_L (*(vu16 *)REG_ADDR_TM0CNT_L)
#define REG_TM0CNT_H (*(vu16 *)REG_ADDR_TM0CNT_H)
#define REG_TM1CNT (*(vu32 *)REG_ADDR_TM1CNT)
#define REG_TM1CNT_L (*(vu16 *)REG_ADDR_TM1CNT_L)
#define REG_TM1CNT_H (*(vu16 *)REG_ADDR_TM1CNT_H)
#define REG_TM2CNT (*(vu32 *)REG_ADDR_TM2CNT)
#define REG_TM2CNT_L (*(vu16 *)REG_ADDR_TM2CNT_L)
#define REG_TM2CNT_H (*(vu16 *)REG_ADDR_TM2CNT_H)
#define REG_TM3CNT (*(vu32 *)REG_ADDR_TM3CNT)
#define REG_TM3CNT_L (*(vu16 *)REG_ADDR_TM3CNT_L)
#define REG_TM3CNT_H (*(vu16 *)REG_ADDR_TM3CNT_H)
#define REG_SIOCNT_L (*(vs8 *)REG_ADDR_SIOCNT)
#define REG_SIOCNT (*(vu16 *)REG_ADDR_SIOCNT)
#define REG_SIODATA8 (*(vu16 *)REG_ADDR_SIODATA8)
#define REG_SIODATA32 (*(vu32 *)REG_ADDR_SIODATA32)
#define REG_SIOMLT_SEND (*(vu16 *)REG_ADDR_SIOMLT_SEND)
#define REG_SIOMLT_RECV (*(vu64 *)REG_ADDR_SIOMLT_RECV)
#define REG_SIOMULTI0 (*(vu16 *)REG_ADDR_SIOMULTI0)
#define REG_SIOMULTI1 (*(vu16 *)REG_ADDR_SIOMULTI1)
#define REG_SIOMULTI2 (*(vu16 *)REG_ADDR_SIOMULTI2)
#define REG_SIOMULTI3 (*(vu16 *)REG_ADDR_SIOMULTI3)
#define REG_KEYINPUT (*(vu16 *)REG_ADDR_KEYINPUT)
#define REG_KEYCNT (*(vu16 *)REG_ADDR_KEYCNT)
#define REG_RCNT (*(vu16 *)REG_ADDR_RCNT)
#define REG_IME (*(vu16 *)REG_ADDR_IME)
#define REG_IE (*(vu16 *)REG_ADDR_IE)
#define REG_IF (*(vu16 *)REG_ADDR_IF)
#define REG_WAITCNT (*(vu16 *)REG_ADDR_WAITCNT)
// I/O register fields
// DISPCNT
#define DISPCNT_MODE_0 0x0000 // BG0: text, BG1: text, BG2: text, BG3: text
#define DISPCNT_MODE_1 0x0001 // BG0: text, BG1: text, BG2: affine, BG3: off
#define DISPCNT_MODE_2 0x0002 // BG0: off, BG1: off, BG2: affine, BG3: affine
#define DISPCNT_MODE_3 0x0003 // Bitmap mode, 240x160, BGR555 color
#define DISPCNT_MODE_4 0x0004 // Bitmap mode, 240x160, 256 color palette
#define DISPCNT_MODE_5 0x0005 // Bitmap mode, 160x128, BGR555 color
#define DISPCNT_HBLANK_INTERVAL 0x0020 // Allow access to OAM during H-Blank
#define DISPCNT_OBJ_1D_MAP 0x0040
#define DISPCNT_FORCED_BLANK 0x0080
#define DISPCNT_BG0_ON 0x0100
#define DISPCNT_BG1_ON 0x0200
#define DISPCNT_BG2_ON 0x0400
#define DISPCNT_BG3_ON 0x0800
#define DISPCNT_BG_ALL_ON 0x0F00
#define DISPCNT_OBJ_ON 0x1000
#define DISPCNT_WIN0_ON 0x2000
#define DISPCNT_WIN1_ON 0x4000
#define DISPCNT_OBJWIN_ON 0x8000
// DISPSTAT
#define DISPSTAT_VBLANK 0x0001 // in V-Blank
#define DISPSTAT_HBLANK 0x0002 // in H-Blank
#define DISPSTAT_VCOUNT 0x0004 // V-Count match
#define DISPSTAT_VBLANK_INTR 0x0008 // V-Blank interrupt enabled
#define DISPSTAT_HBLANK_INTR 0x0010 // H-Blank interrupt enabled
#define DISPSTAT_VCOUNT_INTR 0x0020 // V-Count interrupt enabled
// BGCNT
#define BGCNT_PRIORITY(n) (n) // Values 0 - 3. Lower priority BGs will be drawn on top of higher priority BGs.
#define BGCNT_CHARBASE(n) ((n) << 2) // Values 0 - 3. Base block for tile pixel data.
#define BGCNT_MOSAIC 0x0040
#define BGCNT_16COLOR 0x0000 // 4 bits per pixel
#define BGCNT_256COLOR 0x0080 // 8 bits per pixel
#define BGCNT_SCREENBASE(n) ((n) << 8) // Values 0 - 31. Base block for tile map.
#define BGCNT_WRAP 0x2000 // Only affects affine BGs. Text BGs wrap by default.
#define BGCNT_TXT256x256 0x0000 // Internal screen size size of text mode BG in pixels.
#define BGCNT_TXT512x256 0x4000
#define BGCNT_TXT256x512 0x8000
#define BGCNT_TXT512x512 0xC000
#define BGCNT_AFF128x128 0x0000 // Internal screen size size of affine mode BG in pixels.
#define BGCNT_AFF256x256 0x4000
#define BGCNT_AFF512x512 0x8000
#define BGCNT_AFF1024x1024 0xC000
// WININ/OUT
#define WININ_WIN0_BG0 (1 << 0)
#define WININ_WIN0_BG1 (1 << 1)
#define WININ_WIN0_BG2 (1 << 2)
#define WININ_WIN0_BG3 (1 << 3)
#define WININ_WIN0_BG_ALL (WININ_WIN0_BG0 | WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3)
#define WININ_WIN0_OBJ (1 << 4)
#define WININ_WIN0_CLR (1 << 5)
#define WININ_WIN1_BG0 (1 << 8)
#define WININ_WIN1_BG1 (1 << 9)
#define WININ_WIN1_BG2 (1 << 10)
#define WININ_WIN1_BG3 (1 << 11)
#define WININ_WIN1_BG_ALL (WININ_WIN1_BG0 | WININ_WIN1_BG1 | WININ_WIN1_BG2 | WININ_WIN1_BG3)
#define WININ_WIN1_OBJ (1 << 12)
#define WININ_WIN1_CLR (1 << 13)
#define WINOUT_WIN01_BG0 (1 << 0)
#define WINOUT_WIN01_BG1 (1 << 1)
#define WINOUT_WIN01_BG2 (1 << 2)
#define WINOUT_WIN01_BG3 (1 << 3)
#define WINOUT_WIN01_OBJ (1 << 4)
#define WINOUT_WIN01_CLR (1 << 5)
#define WINOUT_WINOBJ_BG0 (1 << 8)
#define WINOUT_WINOBJ_BG1 (1 << 9)
#define WINOUT_WINOBJ_BG2 (1 << 10)
#define WINOUT_WINOBJ_BG3 (1 << 11)
#define WINOUT_WINOBJ_OBJ (1 << 12)
#define WINOUT_WINOBJ_CLR (1 << 13)
// BLDCNT
// Bits 0-5 select layers for the 1st target
#define BLDCNT_TGT1_BG0 (1 << 0)
#define BLDCNT_TGT1_BG1 (1 << 1)
#define BLDCNT_TGT1_BG2 (1 << 2)
#define BLDCNT_TGT1_BG3 (1 << 3)
#define BLDCNT_TGT1_OBJ (1 << 4)
#define BLDCNT_TGT1_BD (1 << 5)
#define BLDCNT_TGT1_ALL (BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD)
// Bits 6-7 select the special effect
#define BLDCNT_EFFECT_NONE (0 << 6) // no special effect
#define BLDCNT_EFFECT_BLEND (1 << 6) // 1st+2nd targets mixed (controlled by BLDALPHA)
#define BLDCNT_EFFECT_LIGHTEN (2 << 6) // 1st target becomes whiter (controlled by BLDY)
#define BLDCNT_EFFECT_DARKEN (3 << 6) // 1st target becomes blacker (controlled by BLDY)
// Bits 8-13 select layers for the 2nd target
#define BLDCNT_TGT2_BG0 (1 << 8)
#define BLDCNT_TGT2_BG1 (1 << 9)
#define BLDCNT_TGT2_BG2 (1 << 10)
#define BLDCNT_TGT2_BG3 (1 << 11)
#define BLDCNT_TGT2_OBJ (1 << 12)
#define BLDCNT_TGT2_BD (1 << 13)
#define BLDCNT_TGT2_ALL (BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD)
// BLDALPHA
#define BLDALPHA_BLEND(target1, target2) (((target2) << 8) | (target1))
// SOUNDCNT_H
#define SOUND_CGB_MIX_QUARTER 0x0000
#define SOUND_CGB_MIX_HALF 0x0001
#define SOUND_CGB_MIX_FULL 0x0002
#define SOUND_A_MIX_HALF 0x0000
#define SOUND_A_MIX_FULL 0x0004
#define SOUND_B_MIX_HALF 0x0000
#define SOUND_B_MIX_FULL 0x0008
#define SOUND_ALL_MIX_FULL 0x000E
#define SOUND_A_RIGHT_OUTPUT 0x0100
#define SOUND_A_LEFT_OUTPUT 0x0200
#define SOUND_A_TIMER_0 0x0000
#define SOUND_A_TIMER_1 0x0400
#define SOUND_A_FIFO_RESET 0x0800
#define SOUND_B_RIGHT_OUTPUT 0x1000
#define SOUND_B_LEFT_OUTPUT 0x2000
#define SOUND_B_TIMER_0 0x0000
#define SOUND_B_TIMER_1 0x4000
#define SOUND_B_FIFO_RESET 0x8000
// SOUNDCNT_X
#define SOUND_1_ON 0x0001
#define SOUND_2_ON 0x0002
#define SOUND_3_ON 0x0004
#define SOUND_4_ON 0x0008
#define SOUND_MASTER_ENABLE 0x0080
// DMA
#define DMA_DEST_INC 0x0000
#define DMA_DEST_DEC 0x0020
#define DMA_DEST_FIXED 0x0040
#define DMA_DEST_RELOAD 0x0060
#define DMA_SRC_INC 0x0000
#define DMA_SRC_DEC 0x0080
#define DMA_SRC_FIXED 0x0100
#define DMA_REPEAT 0x0200
#define DMA_16BIT 0x0000
#define DMA_32BIT 0x0400
#define DMA_DREQ_ON 0x0800
#define DMA_START_NOW 0x0000
#define DMA_START_VBLANK 0x1000
#define DMA_START_HBLANK 0x2000
#define DMA_START_SPECIAL 0x3000
#define DMA_START_MASK 0x3000
#define DMA_INTR_ENABLE 0x4000
#define DMA_ENABLE 0x8000
// timer
#define TIMER_1CLK 0x00
#define TIMER_64CLK 0x01
#define TIMER_256CLK 0x02
#define TIMER_1024CLK 0x03
#define TIMER_INTR_ENABLE 0x40
#define TIMER_ENABLE 0x80
// serial
#define SIO_ID 0x0030 // Communication ID
#define SIO_8BIT_MODE 0x0000 // Normal 8-bit communication mode
#define SIO_32BIT_MODE 0x1000 // Normal 32-bit communication mode
#define SIO_MULTI_MODE 0x2000 // Multi-player communication mode
#define SIO_UART_MODE 0x3000 // UART communication mode
#define SIO_9600_BPS 0x0000 // baud rate 9600 bps
#define SIO_38400_BPS 0x0001 // 38400 bps
#define SIO_57600_BPS 0x0002 // 57600 bps
#define SIO_115200_BPS 0x0003 // 115200 bps
#define SIO_MULTI_SI 0x0004 // Multi-player communication SI terminal
#define SIO_MULTI_SD 0x0008 // SD terminal
#define SIO_MULTI_BUSY 0x0080
#define SIO_ERROR 0x0040 // Detect error
#define SIO_START 0x0080 // Start transfer
#define SIO_ENABLE 0x0080 // Enable SIO
#define SIO_INTR_ENABLE 0x4000
#define SIO_MULTI_SI_SHIFT 2
#define SIO_MULTI_SI_MASK 0x1
#define SIO_MULTI_DI_SHIFT 3
#define SIO_MULTI_DI_MASK 0x1
// keys
#define A_BUTTON 0x0001
#define B_BUTTON 0x0002
#define SELECT_BUTTON 0x0004
#define START_BUTTON 0x0008
#define DPAD_RIGHT 0x0010
#define DPAD_LEFT 0x0020
#define DPAD_UP 0x0040
#define DPAD_DOWN 0x0080
#define R_BUTTON 0x0100
#define L_BUTTON 0x0200
#define KEYS_MASK 0x03FF
#define KEY_INTR_ENABLE 0x0400
#define KEY_OR_INTR 0x0000
#define KEY_AND_INTR 0x8000
#define DPAD_ANY ((DPAD_RIGHT | DPAD_LEFT | DPAD_UP | DPAD_DOWN))
#define JOY_EXCL_DPAD 0x030F
// interrupt flags
#define INTR_FLAG_VBLANK (1 << 0)
#define INTR_FLAG_HBLANK (1 << 1)
#define INTR_FLAG_VCOUNT (1 << 2)
#define INTR_FLAG_TIMER0 (1 << 3)
#define INTR_FLAG_TIMER1 (1 << 4)
#define INTR_FLAG_TIMER2 (1 << 5)
#define INTR_FLAG_TIMER3 (1 << 6)
#define INTR_FLAG_SERIAL (1 << 7)
#define INTR_FLAG_DMA0 (1 << 8)
#define INTR_FLAG_DMA1 (1 << 9)
#define INTR_FLAG_DMA2 (1 << 10)
#define INTR_FLAG_DMA3 (1 << 11)
#define INTR_FLAG_KEYPAD (1 << 12)
#define INTR_FLAG_GAMEPAK (1 << 13)
// WAITCNT
#define WAITCNT_SRAM_4 (0 << 0)
#define WAITCNT_SRAM_3 (1 << 0)
#define WAITCNT_SRAM_2 (2 << 0)
#define WAITCNT_SRAM_8 (3 << 0)
#define WAITCNT_SRAM_MASK (3 << 0)
#define WAITCNT_WS0_N_4 (0 << 2)
#define WAITCNT_WS0_N_3 (1 << 2)
#define WAITCNT_WS0_N_2 (2 << 2)
#define WAITCNT_WS0_N_8 (3 << 2)
#define WAITCNT_WS0_N_MASK (3 << 2)
#define WAITCNT_WS0_S_2 (0 << 4)
#define WAITCNT_WS0_S_1 (1 << 4)
#define WAITCNT_WS1_N_4 (0 << 5)
#define WAITCNT_WS1_N_3 (1 << 5)
#define WAITCNT_WS1_N_2 (2 << 5)
#define WAITCNT_WS1_N_8 (3 << 5)
#define WAITCNT_WS1_N_MASK (3 << 5)
#define WAITCNT_WS1_S_4 (0 << 7)
#define WAITCNT_WS1_S_1 (1 << 7)
#define WAITCNT_WS2_N_4 (0 << 8)
#define WAITCNT_WS2_N_3 (1 << 8)
#define WAITCNT_WS2_N_2 (2 << 8)
#define WAITCNT_WS2_N_8 (3 << 8)
#define WAITCNT_WS2_N_MASK (3 << 8)
#define WAITCNT_WS2_S_8 (0 << 10)
#define WAITCNT_WS2_S_1 (1 << 10)
#define WAITCNT_PHI_OUT_NONE (0 << 11)
#define WAITCNT_PHI_OUT_4MHZ (1 << 11)
#define WAITCNT_PHI_OUT_8MHZ (2 << 11)
#define WAITCNT_PHI_OUT_16MHZ (3 << 11)
#define WAITCNT_PHI_OUT_MASK (3 << 11)
#define WAITCNT_PREFETCH_ENABLE (1 << 14)
#define WAITCNT_AGB (0 << 15)
#define WAITCNT_CGB (1 << 15)
#endif // GUARD_GBA_IO_REG_H
|