Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/alt/cpu/mmio.cpp
2 views
1
#ifdef CPU_CPP
2
3
uint8 CPU::mmio_read(unsigned addr) {
4
if((addr & 0xffc0) == 0x2140) {
5
synchronize_smp();
6
return smp.port_read(addr & 3);
7
}
8
9
switch(addr & 0xffff) {
10
case 0x2180: {
11
uint8 result = bus.read(0x7e0000 | status.wram_addr);
12
status.wram_addr = (status.wram_addr + 1) & 0x01ffff;
13
return result;
14
}
15
16
case 0x4016: {
17
uint8 result = regs.mdr & 0xfc;
18
result |= input.port1->data() & 3;
19
return result;
20
}
21
22
case 0x4017: {
23
uint8 result = (regs.mdr & 0xe0) | 0x1c;
24
result |= input.port2->data() & 3;
25
if (!status.auto_joypad_poll_enabled) interface()->inputNotify(0x4017);
26
return result;
27
}
28
29
case 0x4210: {
30
uint8 result = (regs.mdr & 0x70);
31
result |= status.nmi_line << 7;
32
result |= 0x02; //CPU revision
33
status.nmi_line = false;
34
return result;
35
}
36
37
case 0x4211: {
38
uint8 result = (regs.mdr & 0x7f);
39
result |= status.irq_line << 7;
40
status.irq_line = false;
41
return result;
42
}
43
44
case 0x4212: {
45
uint8 result = (regs.mdr & 0x3e);
46
unsigned vbstart = ppu.overscan() == false ? 225 : 240;
47
48
if(vcounter() >= vbstart && vcounter() <= vbstart + 2) result |= 0x01;
49
if(hcounter() <= 2 || hcounter() >= 1096) result |= 0x40;
50
if(vcounter() >= vbstart) result |= 0x80;
51
52
return result;
53
}
54
55
case 0x4213:
56
// interface()->inputNotify(0x4213); // if there are lag counter issues with super scope, uncomment this
57
return status.pio;
58
59
case 0x4214: return status.rddiv >> 0;
60
case 0x4215: return status.rddiv >> 8;
61
case 0x4216: return status.rdmpy >> 0;
62
case 0x4217: return status.rdmpy >> 8;
63
64
case 0x4218: interface()->inputNotify(0x4218); return status.joy1l;
65
case 0x4219: interface()->inputNotify(0x4219); return status.joy1h;
66
case 0x421a: interface()->inputNotify(0x421a); return status.joy2l;
67
case 0x421b: interface()->inputNotify(0x421b); return status.joy2h;
68
case 0x421c: interface()->inputNotify(0x421c); return status.joy3l;
69
case 0x421d: interface()->inputNotify(0x421d); return status.joy3h;
70
case 0x421e: interface()->inputNotify(0x421e); return status.joy4l;
71
case 0x421f: interface()->inputNotify(0x421f); return status.joy4h;
72
}
73
74
if((addr & 0xff80) == 0x4300) {
75
unsigned i = (addr >> 4) & 7;
76
switch(addr & 0xff8f) {
77
case 0x4300: {
78
return (channel[i].direction << 7)
79
| (channel[i].indirect << 6)
80
| (channel[i].unused << 5)
81
| (channel[i].reverse_transfer << 4)
82
| (channel[i].fixed_transfer << 3)
83
| (channel[i].transfer_mode << 0);
84
}
85
86
case 0x4301: return channel[i].dest_addr;
87
case 0x4302: return channel[i].source_addr >> 0;
88
case 0x4303: return channel[i].source_addr >> 8;
89
case 0x4304: return channel[i].source_bank;
90
case 0x4305: return channel[i].transfer_size >> 0;
91
case 0x4306: return channel[i].transfer_size >> 8;
92
case 0x4307: return channel[i].indirect_bank;
93
case 0x4308: return channel[i].hdma_addr >> 0;
94
case 0x4309: return channel[i].hdma_addr >> 8;
95
case 0x430a: return channel[i].line_counter;
96
case 0x430b: case 0x430f: return channel[i].unknown;
97
}
98
}
99
100
return regs.mdr;
101
}
102
103
void CPU::mmio_write(unsigned addr, uint8 data) {
104
if((addr & 0xffc0) == 0x2140) {
105
synchronize_smp();
106
port_write(addr & 3, data);
107
return;
108
}
109
110
switch(addr & 0xffff) {
111
case 0x2180: {
112
bus.write(0x7e0000 | status.wram_addr, data);
113
status.wram_addr = (status.wram_addr + 1) & 0x01ffff;
114
return;
115
}
116
117
case 0x2181: {
118
status.wram_addr = (status.wram_addr & 0x01ff00) | (data << 0);
119
return;
120
}
121
122
case 0x2182: {
123
status.wram_addr = (status.wram_addr & 0x0100ff) | (data << 8);
124
return;
125
}
126
127
case 0x2183: {
128
status.wram_addr = (status.wram_addr & 0x00ffff) | ((data & 1) << 16);
129
return;
130
}
131
132
case 0x4016: {
133
input.port1->latch(data & 1);
134
input.port2->latch(data & 1);
135
interface()->inputNotify(data & 1); // latch notify
136
if (!status.auto_joypad_poll_enabled) { interface()->inputNotify(0x4016); }
137
return;
138
}
139
140
case 0x4200: {
141
bool nmi_enabled = status.nmi_enabled;
142
bool virq_enabled = status.virq_enabled;
143
bool hirq_enabled = status.hirq_enabled;
144
145
status.nmi_enabled = data & 0x80;
146
status.virq_enabled = data & 0x20;
147
status.hirq_enabled = data & 0x10;
148
status.auto_joypad_poll_enabled = data & 0x01;
149
150
if(!nmi_enabled && status.nmi_enabled && status.nmi_line) {
151
status.nmi_transition = true;
152
}
153
154
if(status.virq_enabled && !status.hirq_enabled && status.irq_line) {
155
status.irq_transition = true;
156
}
157
158
if(!status.virq_enabled && !status.hirq_enabled) {
159
status.irq_line = false;
160
status.irq_transition = false;
161
}
162
163
status.irq_lock = true;
164
return;
165
}
166
167
case 0x4201: {
168
if((status.pio & 0x80) && !(data & 0x80)) ppu.latch_counters();
169
status.pio = data;
170
}
171
172
case 0x4202: {
173
status.wrmpya = data;
174
return;
175
}
176
177
case 0x4203: {
178
status.wrmpyb = data;
179
status.rdmpy = status.wrmpya * status.wrmpyb;
180
return;
181
}
182
183
case 0x4204: {
184
status.wrdiva = (status.wrdiva & 0xff00) | (data << 0);
185
return;
186
}
187
188
case 0x4205: {
189
status.wrdiva = (data << 8) | (status.wrdiva & 0x00ff);
190
return;
191
}
192
193
case 0x4206: {
194
status.wrdivb = data;
195
status.rddiv = status.wrdivb ? status.wrdiva / status.wrdivb : 0xffff;
196
status.rdmpy = status.wrdivb ? status.wrdiva % status.wrdivb : status.wrdiva;
197
return;
198
}
199
200
case 0x4207: {
201
status.htime = (status.htime & 0x0100) | (data << 0);
202
return;
203
}
204
205
case 0x4208: {
206
status.htime = ((data & 1) << 8) | (status.htime & 0x00ff);
207
return;
208
}
209
210
case 0x4209: {
211
status.vtime = (status.vtime & 0x0100) | (data << 0);
212
return;
213
}
214
215
case 0x420a: {
216
status.vtime = ((data & 1) << 8) | (status.vtime & 0x00ff);
217
return;
218
}
219
220
case 0x420b: {
221
for(unsigned i = 0; i < 8; i++) channel[i].dma_enabled = data & (1 << i);
222
if(data) dma_run();
223
return;
224
}
225
226
case 0x420c: {
227
for(unsigned i = 0; i < 8; i++) channel[i].hdma_enabled = data & (1 << i);
228
return;
229
}
230
231
case 0x420d: {
232
status.rom_speed = data & 1 ? 6 : 8;
233
return;
234
}
235
}
236
237
if((addr & 0xff80) == 0x4300) {
238
unsigned i = (addr >> 4) & 7;
239
switch(addr & 0xff8f) {
240
case 0x4300: {
241
channel[i].direction = data & 0x80;
242
channel[i].indirect = data & 0x40;
243
channel[i].unused = data & 0x20;
244
channel[i].reverse_transfer = data & 0x10;
245
channel[i].fixed_transfer = data & 0x08;
246
channel[i].transfer_mode = data & 0x07;
247
return;
248
}
249
250
case 0x4301: {
251
channel[i].dest_addr = data;
252
return;
253
}
254
255
case 0x4302: {
256
channel[i].source_addr = (channel[i].source_addr & 0xff00) | (data << 0);
257
return;
258
}
259
260
case 0x4303: {
261
channel[i].source_addr = (data << 8) | (channel[i].source_addr & 0x00ff);
262
return;
263
}
264
265
case 0x4304: {
266
channel[i].source_bank = data;
267
return;
268
}
269
270
case 0x4305: {
271
channel[i].transfer_size = (channel[i].transfer_size & 0xff00) | (data << 0);
272
return;
273
}
274
275
case 0x4306: {
276
channel[i].transfer_size = (data << 8) | (channel[i].transfer_size & 0x00ff);
277
return;
278
}
279
280
case 0x4307: {
281
channel[i].indirect_bank = data;
282
return;
283
}
284
285
case 0x4308: {
286
channel[i].hdma_addr = (channel[i].hdma_addr & 0xff00) | (data << 0);
287
return;
288
}
289
290
case 0x4309: {
291
channel[i].hdma_addr = (data << 8) | (channel[i].hdma_addr & 0x00ff);
292
return;
293
}
294
295
case 0x430a: {
296
channel[i].line_counter = data;
297
return;
298
}
299
300
case 0x430b: case 0x430f: {
301
channel[i].unknown = data;
302
return;
303
}
304
}
305
}
306
}
307
308
#endif
309
310