src/gba/gba-io.c (view raw)
1#include "gba-io.h"
2
3#include "gba-video.h"
4
5void GBAIOInit(struct GBA* gba) {
6 gba->memory.io[REG_KEYINPUT >> 1] = 0x3FF;
7}
8
9void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
10 switch (address) {
11 case REG_DISPSTAT:
12 GBAVideoWriteDISPSTAT(&gba->video, value);
13 break;
14 case REG_DMA0CNT_LO:
15 GBAMemoryWriteDMACNT_LO(&gba->memory, 0, value);
16 break;
17 case REG_DMA0CNT_HI:
18 value = GBAMemoryWriteDMACNT_HI(&gba->memory, 0, value);
19 break;
20 case REG_DMA1CNT_LO:
21 GBAMemoryWriteDMACNT_LO(&gba->memory, 1, value);
22 break;
23 case REG_DMA1CNT_HI:
24 value = GBAMemoryWriteDMACNT_HI(&gba->memory, 1, value);
25 break;
26 case REG_DMA2CNT_LO:
27 GBAMemoryWriteDMACNT_LO(&gba->memory, 2, value);
28 break;
29 case REG_DMA2CNT_HI:
30 value = GBAMemoryWriteDMACNT_HI(&gba->memory, 2, value);
31 break;
32 case REG_DMA3CNT_LO:
33 GBAMemoryWriteDMACNT_LO(&gba->memory, 3, value);
34 break;
35 case REG_DMA3CNT_HI:
36 value = GBAMemoryWriteDMACNT_HI(&gba->memory, 3, value);
37 break;
38
39 case REG_WAITCNT:
40 GBAAdjustWaitstates(&gba->memory, value);
41 break;
42 case REG_IE:
43 GBAWriteIE(gba, value);
44 break;
45 case REG_IF:
46 value = gba->memory.io[REG_IF >> 1] & ~value;
47 break;
48 case REG_IME:
49 GBAWriteIME(gba, value);
50 break;
51 case REG_HALTCNT:
52 value &= 0x80;
53 if (!value) {
54 GBAHalt(gba);
55 } else {
56 GBALog(GBA_LOG_STUB, "Stop unimplemented");
57 }
58 return;
59 default:
60 GBALog(GBA_LOG_STUB, "Stub I/O register write: %03x", address);
61 break;
62 }
63 gba->memory.io[address >> 1] = value;
64}
65
66void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
67 switch (address) {
68 case REG_DMA0SAD_LO:
69 GBAMemoryWriteDMASAD(&gba->memory, 0, value);
70 break;
71 case REG_DMA0DAD_LO:
72 GBAMemoryWriteDMADAD(&gba->memory, 0, value);
73 break;
74 case REG_DMA1SAD_LO:
75 GBAMemoryWriteDMASAD(&gba->memory, 1, value);
76 break;
77 case REG_DMA1DAD_LO:
78 GBAMemoryWriteDMADAD(&gba->memory, 1, value);
79 break;
80 case REG_DMA2SAD_LO:
81 GBAMemoryWriteDMASAD(&gba->memory, 2, value);
82 break;
83 case REG_DMA2DAD_LO:
84 GBAMemoryWriteDMADAD(&gba->memory, 2, value);
85 break;
86 case REG_DMA3SAD_LO:
87 GBAMemoryWriteDMASAD(&gba->memory, 3, value);
88 break;
89 case REG_DMA3DAD_LO:
90 GBAMemoryWriteDMADAD(&gba->memory, 3, value);
91 break;
92 default:
93 GBAIOWrite(gba, address, value & 0xFFFF);
94 GBAIOWrite(gba, address | 2, value >> 16);
95 break;
96 }
97}
98
99uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
100 switch (address) {
101 case REG_DISPSTAT:
102 return gba->memory.io[REG_DISPSTAT >> 1] | GBAVideoReadDISPSTAT(&gba->video);
103 break;
104 case REG_DMA0CNT_LO:
105 case REG_DMA1CNT_LO:
106 case REG_DMA2CNT_LO:
107 case REG_DMA3CNT_LO:
108 // Write-only register
109 return 0;
110 case REG_VCOUNT:
111 case REG_DMA0CNT_HI:
112 case REG_DMA1CNT_HI:
113 case REG_DMA2CNT_HI:
114 case REG_DMA3CNT_HI:
115 case REG_IE:
116 case REG_IF:
117 case REG_WAITCNT:
118 case REG_IME:
119 // Handled transparently by registers
120 break;
121 default:
122 GBALog(GBA_LOG_STUB, "Stub I/O register read: %03x", address);
123 break;
124 }
125 return gba->memory.io[address >> 1];
126}