Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/gameboy/cpu/mmio/mmio.cpp
2 views
1
#ifdef CPU_CPP
2
3
unsigned CPU::wram_addr(uint16 addr) const {
4
addr &= 0x1fff;
5
if(addr < 0x1000) return addr;
6
auto bank = status.wram_bank + (status.wram_bank == 0);
7
return (bank * 0x1000) + (addr & 0x0fff);
8
}
9
10
void CPU::mmio_joyp_poll() {
11
unsigned button = 0, dpad = 0;
12
13
button |= interface->inputPoll((unsigned)Input::Start) << 3;
14
button |= interface->inputPoll((unsigned)Input::Select) << 2;
15
button |= interface->inputPoll((unsigned)Input::B) << 1;
16
button |= interface->inputPoll((unsigned)Input::A) << 0;
17
18
dpad |= interface->inputPoll((unsigned)Input::Down) << 3;
19
dpad |= interface->inputPoll((unsigned)Input::Up) << 2;
20
dpad |= interface->inputPoll((unsigned)Input::Left) << 1;
21
dpad |= interface->inputPoll((unsigned)Input::Right) << 0;
22
23
status.joyp = 0x0f;
24
if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mlt_req;
25
if(status.p15 == 0) status.joyp &= button ^ 0x0f;
26
if(status.p14 == 0) status.joyp &= dpad ^ 0x0f;
27
if(status.joyp != 0x0f) interrupt_raise(Interrupt::Joypad);
28
}
29
30
uint8 CPU::mmio_read(uint16 addr) {
31
if(addr >= 0xc000 && addr <= 0xfdff) return wram[wram_addr(addr)];
32
if(addr >= 0xff80 && addr <= 0xfffe) return hram[addr & 0x7f];
33
34
if(addr == 0xff00) { //JOYP
35
return (status.p15 << 5)
36
| (status.p14 << 4)
37
| (status.joyp << 0);
38
}
39
40
if(addr == 0xff01) { //SB
41
return 0xff;
42
}
43
44
if(addr == 0xff02) { //SC
45
return (status.serial_transfer << 7)
46
| (status.serial_clock << 0);
47
}
48
49
if(addr == 0xff04) { //DIV
50
return status.div;
51
}
52
53
if(addr == 0xff05) { //TIMA
54
return status.tima;
55
}
56
57
if(addr == 0xff06) { //TMA
58
return status.tma;
59
}
60
61
if(addr == 0xff07) { //TAC
62
return (status.timer_enable << 2)
63
| (status.timer_clock << 0);
64
}
65
66
if(addr == 0xff0f) { //IF
67
return (status.interrupt_request_joypad << 4)
68
| (status.interrupt_request_serial << 3)
69
| (status.interrupt_request_timer << 2)
70
| (status.interrupt_request_stat << 1)
71
| (status.interrupt_request_vblank << 0);
72
}
73
74
if(addr == 0xff4d) { //KEY1
75
return (status.speed_double << 7);
76
}
77
78
if(addr == 0xff55) { //HDMA5
79
return (status.dma_length / 16) - 1;
80
}
81
82
if(addr == 0xff56) { //RP
83
return 0x02;
84
}
85
86
if(addr == 0xff6c) { //???
87
return 0xfe | status.ff6c;
88
}
89
90
if(addr == 0xff70) { //SVBK
91
return status.wram_bank;
92
}
93
94
if(addr == 0xff72) { //???
95
return status.ff72;
96
}
97
98
if(addr == 0xff73) { //???
99
return status.ff73;
100
}
101
102
if(addr == 0xff74) { //???
103
return status.ff74;
104
}
105
106
if(addr == 0xff75) { //???
107
return 0x8f | status.ff75;
108
}
109
110
if(addr == 0xff76) { //???
111
return 0x00;
112
}
113
114
if(addr == 0xff77) { //???
115
return 0x00;
116
}
117
118
if(addr == 0xffff) { //IE
119
return (status.interrupt_enable_joypad << 4)
120
| (status.interrupt_enable_serial << 3)
121
| (status.interrupt_enable_timer << 2)
122
| (status.interrupt_enable_stat << 1)
123
| (status.interrupt_enable_vblank << 0);
124
}
125
126
return 0x00;
127
}
128
129
void CPU::mmio_write(uint16 addr, uint8 data) {
130
if(addr >= 0xc000 && addr <= 0xfdff) { wram[wram_addr(addr)] = data; return; }
131
if(addr >= 0xff80 && addr <= 0xfffe) { hram[addr & 0x7f] = data; return; }
132
133
if(addr == 0xff00) { //JOYP
134
status.p15 = data & 0x20;
135
status.p14 = data & 0x10;
136
interface->joypWrite(status.p15, status.p14);
137
mmio_joyp_poll();
138
return;
139
}
140
141
if(addr == 0xff01) { //SB
142
status.serial_data = data;
143
return;
144
}
145
146
if(addr == 0xff02) { //SC
147
status.serial_transfer = data & 0x80;
148
status.serial_clock = data & 0x01;
149
if(status.serial_transfer) status.serial_bits = 8;
150
return;
151
}
152
153
if(addr == 0xff04) { //DIV
154
status.div = 0;
155
return;
156
}
157
158
if(addr == 0xff05) { //TIMA
159
status.tima = data;
160
return;
161
}
162
163
if(addr == 0xff06) { //TMA
164
status.tma = data;
165
return;
166
}
167
168
if(addr == 0xff07) { //TAC
169
status.timer_enable = data & 0x04;
170
status.timer_clock = data & 0x03;
171
return;
172
}
173
174
if(addr == 0xff0f) { //IF
175
status.interrupt_request_joypad = data & 0x10;
176
status.interrupt_request_serial = data & 0x08;
177
status.interrupt_request_timer = data & 0x04;
178
status.interrupt_request_stat = data & 0x02;
179
status.interrupt_request_vblank = data & 0x01;
180
return;
181
}
182
183
if(addr == 0xff46) { //DMA
184
for(unsigned n = 0x00; n <= 0x9f; n++) {
185
bus.write(0xfe00 + n, bus.read((data << 8) + n));
186
add_clocks(4);
187
}
188
return;
189
}
190
191
if(addr == 0xff4d) { //KEY1
192
status.speed_switch = data & 0x01;
193
return;
194
}
195
196
if(addr == 0xff51) { //HDMA1
197
status.dma_source = (status.dma_source & 0x00ff) | (data << 8);
198
return;
199
}
200
201
if(addr == 0xff52) { //HDMA2
202
status.dma_source = (status.dma_source & 0xff00) | (data << 0);
203
return;
204
}
205
206
if(addr == 0xff53) { //HDMA3
207
status.dma_target = (status.dma_target & 0x00ff) | (data << 8);
208
return;
209
}
210
211
if(addr == 0xff54) { //HDMA4
212
status.dma_target = (status.dma_target & 0xff00) | (data << 0);
213
return;
214
}
215
216
if(addr == 0xff55) { //HDMA5
217
status.dma_mode = data & 0x80;
218
status.dma_length = ((data & 0x7f) + 1) * 16;
219
220
if(status.dma_mode == 0) do {
221
bus.write(status.dma_target++, bus.read(status.dma_source++));
222
add_clocks(4 << status.speed_double);
223
} while(--status.dma_length);
224
return;
225
}
226
227
if(addr == 0xff56) { //RP
228
return;
229
}
230
231
if(addr == 0xff6c) { //???
232
status.ff6c = data & 0x01;
233
return;
234
}
235
236
if(addr == 0xff72) { //???
237
status.ff72 = data;
238
return;
239
}
240
241
if(addr == 0xff73) { //???
242
status.ff73 = data;
243
return;
244
}
245
246
if(addr == 0xff74) { //???
247
status.ff74 = data;
248
return;
249
}
250
251
if(addr == 0xff75) { //???
252
status.ff75 = data & 0x70;
253
return;
254
}
255
256
if(addr == 0xff70) { //SVBK
257
status.wram_bank = data & 0x07;
258
return;
259
}
260
261
if(addr == 0xffff) { //IE
262
status.interrupt_enable_joypad = data & 0x10;
263
status.interrupt_enable_serial = data & 0x08;
264
status.interrupt_enable_timer = data & 0x04;
265
status.interrupt_enable_stat = data & 0x02;
266
status.interrupt_enable_vblank = data & 0x01;
267
return;
268
}
269
}
270
271
#endif
272
273