Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/chip/sa1/mmio/mmio.cpp
2 views
1
#ifdef SA1_CPP
2
3
//(CCNT) SA-1 control
4
void SA1::mmio_w2200(uint8 data) {
5
if(mmio.sa1_resb && !(data & 0x80)) {
6
//reset SA-1 CPU
7
regs.pc.w = mmio.crv;
8
regs.pc.b = 0x00;
9
}
10
11
mmio.sa1_irq = (data & 0x80);
12
mmio.sa1_rdyb = (data & 0x40);
13
mmio.sa1_resb = (data & 0x20);
14
mmio.sa1_nmi = (data & 0x10);
15
mmio.smeg = (data & 0x0f);
16
17
if(mmio.sa1_irq) {
18
mmio.sa1_irqfl = true;
19
if(mmio.sa1_irqen) mmio.sa1_irqcl = 0;
20
}
21
22
if(mmio.sa1_nmi) {
23
mmio.sa1_nmifl = true;
24
if(mmio.sa1_nmien) mmio.sa1_nmicl = 0;
25
}
26
}
27
28
//(SIE) S-CPU interrupt enable
29
void SA1::mmio_w2201(uint8 data) {
30
if(!mmio.cpu_irqen && (data & 0x80)) {
31
if(mmio.cpu_irqfl) {
32
mmio.cpu_irqcl = 0;
33
cpu.regs.irq = 1;
34
}
35
}
36
37
if(!mmio.chdma_irqen && (data & 0x20)) {
38
if(mmio.chdma_irqfl) {
39
mmio.chdma_irqcl = 0;
40
cpu.regs.irq = 1;
41
}
42
}
43
44
mmio.cpu_irqen = (data & 0x80);
45
mmio.chdma_irqen = (data & 0x20);
46
}
47
48
//(SIC) S-CPU interrupt clear
49
void SA1::mmio_w2202(uint8 data) {
50
mmio.cpu_irqcl = (data & 0x80);
51
mmio.chdma_irqcl = (data & 0x20);
52
53
if(mmio.cpu_irqcl ) mmio.cpu_irqfl = false;
54
if(mmio.chdma_irqcl) mmio.chdma_irqfl = false;
55
56
if(!mmio.cpu_irqfl && !mmio.chdma_irqfl) cpu.regs.irq = 0;
57
}
58
59
//(CRV) SA-1 reset vector
60
void SA1::mmio_w2203(uint8 data) { mmio.crv = (mmio.crv & 0xff00) | data; }
61
void SA1::mmio_w2204(uint8 data) { mmio.crv = (data << 8) | (mmio.crv & 0xff); }
62
63
//(CNV) SA-1 NMI vector
64
void SA1::mmio_w2205(uint8 data) { mmio.cnv = (mmio.cnv & 0xff00) | data; }
65
void SA1::mmio_w2206(uint8 data) { mmio.cnv = (data << 8) | (mmio.cnv & 0xff); }
66
67
//(CIV) SA-1 IRQ vector
68
void SA1::mmio_w2207(uint8 data) { mmio.civ = (mmio.civ & 0xff00) | data; }
69
void SA1::mmio_w2208(uint8 data) { mmio.civ = (data << 8) | (mmio.civ & 0xff); }
70
71
//(SCNT) S-CPU control
72
void SA1::mmio_w2209(uint8 data) {
73
mmio.cpu_irq = (data & 0x80);
74
mmio.cpu_ivsw = (data & 0x40);
75
mmio.cpu_nvsw = (data & 0x10);
76
mmio.cmeg = (data & 0x0f);
77
78
if(mmio.cpu_irq) {
79
mmio.cpu_irqfl = true;
80
if(mmio.cpu_irqen) {
81
mmio.cpu_irqcl = 0;
82
cpu.regs.irq = 1;
83
}
84
}
85
}
86
87
//(CIE) SA-1 interrupt enable
88
void SA1::mmio_w220a(uint8 data) {
89
if(!mmio.sa1_irqen && (data & 0x80) && mmio.sa1_irqfl ) mmio.sa1_irqcl = 0;
90
if(!mmio.timer_irqen && (data & 0x40) && mmio.timer_irqfl) mmio.timer_irqcl = 0;
91
if(!mmio.dma_irqen && (data & 0x20) && mmio.dma_irqfl ) mmio.dma_irqcl = 0;
92
if(!mmio.sa1_nmien && (data & 0x10) && mmio.sa1_nmifl ) mmio.sa1_nmicl = 0;
93
94
mmio.sa1_irqen = (data & 0x80);
95
mmio.timer_irqen = (data & 0x40);
96
mmio.dma_irqen = (data & 0x20);
97
mmio.sa1_nmien = (data & 0x10);
98
}
99
100
//(CIC) SA-1 interrupt clear
101
void SA1::mmio_w220b(uint8 data) {
102
mmio.sa1_irqcl = (data & 0x80);
103
mmio.timer_irqcl = (data & 0x40);
104
mmio.dma_irqcl = (data & 0x20);
105
mmio.sa1_nmicl = (data & 0x10);
106
107
if(mmio.sa1_irqcl) mmio.sa1_irqfl = false;
108
if(mmio.timer_irqcl) mmio.timer_irqfl = false;
109
if(mmio.dma_irqcl) mmio.dma_irqfl = false;
110
if(mmio.sa1_nmicl) mmio.sa1_nmifl = false;
111
}
112
113
//(SNV) S-CPU NMI vector
114
void SA1::mmio_w220c(uint8 data) { mmio.snv = (mmio.snv & 0xff00) | data; }
115
void SA1::mmio_w220d(uint8 data) { mmio.snv = (data << 8) | (mmio.snv & 0xff); }
116
117
//(SIV) S-CPU IRQ vector
118
void SA1::mmio_w220e(uint8 data) { mmio.siv = (mmio.siv & 0xff00) | data; }
119
void SA1::mmio_w220f(uint8 data) { mmio.siv = (data << 8) | (mmio.siv & 0xff); }
120
121
//(TMC) H/V timer control
122
void SA1::mmio_w2210(uint8 data) {
123
mmio.hvselb = (data & 0x80);
124
mmio.ven = (data & 0x02);
125
mmio.hen = (data & 0x01);
126
}
127
128
//(CTR) SA-1 timer restart
129
void SA1::mmio_w2211(uint8 data) {
130
status.vcounter = 0;
131
status.hcounter = 0;
132
}
133
134
//(HCNT) H-count
135
void SA1::mmio_w2212(uint8 data) { mmio.hcnt = (mmio.hcnt & 0xff00) | (data << 0); }
136
void SA1::mmio_w2213(uint8 data) { mmio.hcnt = (mmio.hcnt & 0x00ff) | (data << 8); }
137
138
//(VCNT) V-count
139
void SA1::mmio_w2214(uint8 data) { mmio.vcnt = (mmio.vcnt & 0xff00) | (data << 0); }
140
void SA1::mmio_w2215(uint8 data) { mmio.vcnt = (mmio.vcnt & 0x00ff) | (data << 8); }
141
142
//(CXB) Super MMC bank C
143
void SA1::mmio_w2220(uint8 data) {
144
mmio.cbmode = (data & 0x80);
145
mmio.cb = (data & 0x07);
146
}
147
148
//(DXB) Super MMC bank D
149
void SA1::mmio_w2221(uint8 data) {
150
mmio.dbmode = (data & 0x80);
151
mmio.db = (data & 0x07);
152
}
153
154
//(EXB) Super MMC bank E
155
void SA1::mmio_w2222(uint8 data) {
156
mmio.ebmode = (data & 0x80);
157
mmio.eb = (data & 0x07);
158
}
159
160
//(FXB) Super MMC bank F
161
void SA1::mmio_w2223(uint8 data) {
162
mmio.fbmode = (data & 0x80);
163
mmio.fb = (data & 0x07);
164
}
165
166
//(BMAPS) S-CPU BW-RAM address mapping
167
void SA1::mmio_w2224(uint8 data) {
168
mmio.sbm = (data & 0x1f);
169
}
170
171
//(BMAP) SA-1 BW-RAM address mapping
172
void SA1::mmio_w2225(uint8 data) {
173
mmio.sw46 = (data & 0x80);
174
mmio.cbm = (data & 0x7f);
175
}
176
177
//(SWBE) S-CPU BW-RAM write enable
178
void SA1::mmio_w2226(uint8 data) {
179
mmio.swen = (data & 0x80);
180
}
181
182
//(CWBE) SA-1 BW-RAM write enable
183
void SA1::mmio_w2227(uint8 data) {
184
mmio.cwen = (data & 0x80);
185
}
186
187
//(BWPA) BW-RAM write-protected area
188
void SA1::mmio_w2228(uint8 data) {
189
mmio.bwp = (data & 0x0f);
190
}
191
192
//(SIWP) S-CPU I-RAM write protection
193
void SA1::mmio_w2229(uint8 data) {
194
mmio.siwp = data;
195
}
196
197
//(CIWP) SA-1 I-RAM write protection
198
void SA1::mmio_w222a(uint8 data) {
199
mmio.ciwp = data;
200
}
201
202
//(DCNT) DMA control
203
void SA1::mmio_w2230(uint8 data) {
204
mmio.dmaen = (data & 0x80);
205
mmio.dprio = (data & 0x40);
206
mmio.cden = (data & 0x20);
207
mmio.cdsel = (data & 0x10);
208
mmio.dd = (data & 0x04);
209
mmio.sd = (data & 0x03);
210
211
if(mmio.dmaen == 0) dma.line = 0;
212
}
213
214
//(CDMA) character conversion DMA parameters
215
void SA1::mmio_w2231(uint8 data) {
216
mmio.chdend = (data & 0x80);
217
mmio.dmasize = (data >> 2) & 7;
218
mmio.dmacb = (data & 0x03);
219
220
if(mmio.chdend) cpubwram.dma = false;
221
if(mmio.dmasize > 5) mmio.dmasize = 5;
222
if(mmio.dmacb > 2) mmio.dmacb = 2;
223
}
224
225
//(SDA) DMA source device start address
226
void SA1::mmio_w2232(uint8 data) { mmio.dsa = (mmio.dsa & 0xffff00) | (data << 0); }
227
void SA1::mmio_w2233(uint8 data) { mmio.dsa = (mmio.dsa & 0xff00ff) | (data << 8); }
228
void SA1::mmio_w2234(uint8 data) { mmio.dsa = (mmio.dsa & 0x00ffff) | (data << 16); }
229
230
//(DDA) DMA destination start address
231
void SA1::mmio_w2235(uint8 data) {
232
mmio.dda = (mmio.dda & 0xffff00) | (data << 0);
233
}
234
235
void SA1::mmio_w2236(uint8 data) {
236
mmio.dda = (mmio.dda & 0xff00ff) | (data << 8);
237
238
if(mmio.dmaen == true) {
239
if(mmio.cden == 0 && mmio.dd == DMA::DestIRAM) {
240
dma_normal();
241
} else if(mmio.cden == 1 && mmio.cdsel == 1) {
242
dma_cc1();
243
}
244
}
245
}
246
247
void SA1::mmio_w2237(uint8 data) {
248
mmio.dda = (mmio.dda & 0x00ffff) | (data << 16);
249
250
if(mmio.dmaen == true) {
251
if(mmio.cden == 0 && mmio.dd == DMA::DestBWRAM) {
252
dma_normal();
253
}
254
}
255
}
256
257
//(DTC) DMA terminal counter
258
void SA1::mmio_w2238(uint8 data) { mmio.dtc = (mmio.dtc & 0xff00) | (data << 0); }
259
void SA1::mmio_w2239(uint8 data) { mmio.dtc = (mmio.dtc & 0x00ff) | (data << 8); }
260
261
//(BBF) BW-RAM bitmap format
262
void SA1::mmio_w223f(uint8 data) {
263
mmio.bbf = (data & 0x80);
264
}
265
266
//(BRF) bitmap register files
267
void SA1::mmio_w2240(uint8 data) { mmio.brf[ 0] = data; }
268
void SA1::mmio_w2241(uint8 data) { mmio.brf[ 1] = data; }
269
void SA1::mmio_w2242(uint8 data) { mmio.brf[ 2] = data; }
270
void SA1::mmio_w2243(uint8 data) { mmio.brf[ 3] = data; }
271
void SA1::mmio_w2244(uint8 data) { mmio.brf[ 4] = data; }
272
void SA1::mmio_w2245(uint8 data) { mmio.brf[ 5] = data; }
273
void SA1::mmio_w2246(uint8 data) { mmio.brf[ 6] = data; }
274
void SA1::mmio_w2247(uint8 data) { mmio.brf[ 7] = data;
275
if(mmio.dmaen == true) {
276
if(mmio.cden == 1 && mmio.cdsel == 0) {
277
dma_cc2();
278
}
279
}
280
}
281
282
void SA1::mmio_w2248(uint8 data) { mmio.brf[ 8] = data; }
283
void SA1::mmio_w2249(uint8 data) { mmio.brf[ 9] = data; }
284
void SA1::mmio_w224a(uint8 data) { mmio.brf[10] = data; }
285
void SA1::mmio_w224b(uint8 data) { mmio.brf[11] = data; }
286
void SA1::mmio_w224c(uint8 data) { mmio.brf[12] = data; }
287
void SA1::mmio_w224d(uint8 data) { mmio.brf[13] = data; }
288
void SA1::mmio_w224e(uint8 data) { mmio.brf[14] = data; }
289
void SA1::mmio_w224f(uint8 data) { mmio.brf[15] = data;
290
if(mmio.dmaen == true) {
291
if(mmio.cden == 1 && mmio.cdsel == 0) {
292
dma_cc2();
293
}
294
}
295
}
296
297
//(MCNT) arithmetic control
298
void SA1::mmio_w2250(uint8 data) {
299
mmio.acm = (data & 0x02);
300
mmio.md = (data & 0x01);
301
302
if(mmio.acm) mmio.mr = 0;
303
}
304
305
//(MAL) multiplicand / dividend low
306
void SA1::mmio_w2251(uint8 data) {
307
mmio.ma = (mmio.ma & 0xff00) | data;
308
}
309
310
//(MAH) multiplicand / dividend high
311
void SA1::mmio_w2252(uint8 data) {
312
mmio.ma = (data << 8) | (mmio.ma & 0x00ff);
313
}
314
315
//(MBL) multiplier / divisor low
316
void SA1::mmio_w2253(uint8 data) {
317
mmio.mb = (mmio.mb & 0xff00) | data;
318
}
319
320
//(MBH) multiplier / divisor high
321
//multiplication / cumulative sum only resets MB
322
//division resets both MA and MB
323
void SA1::mmio_w2254(uint8 data) {
324
mmio.mb = (data << 8) | (mmio.mb & 0x00ff);
325
326
if(mmio.acm == 0) {
327
if(mmio.md == 0) {
328
//signed multiplication
329
mmio.mr = (int16)mmio.ma * (int16)mmio.mb;
330
mmio.mb = 0;
331
} else {
332
//unsigned division
333
if(mmio.mb == 0) {
334
mmio.mr = 0;
335
} else {
336
int16 quotient = (int16)mmio.ma / (uint16)mmio.mb;
337
uint16 remainder = (int16)mmio.ma % (uint16)mmio.mb;
338
mmio.mr = (remainder << 16) | quotient;
339
}
340
mmio.ma = 0;
341
mmio.mb = 0;
342
}
343
} else {
344
//sigma (accumulative multiplication)
345
mmio.mr += (int16)mmio.ma * (int16)mmio.mb;
346
mmio.overflow = (mmio.mr >= (1ULL << 40));
347
mmio.mr &= (1ULL << 40) - 1;
348
mmio.mb = 0;
349
}
350
}
351
352
//(VBD) variable-length bit processing
353
void SA1::mmio_w2258(uint8 data) {
354
mmio.hl = (data & 0x80);
355
mmio.vb = (data & 0x0f);
356
if(mmio.vb == 0) mmio.vb = 16;
357
358
if(mmio.hl == 0) {
359
//fixed mode
360
mmio.vbit += mmio.vb;
361
mmio.va += (mmio.vbit >> 3);
362
mmio.vbit &= 7;
363
}
364
}
365
366
//(VDA) variable-length bit game pak ROM start address
367
void SA1::mmio_w2259(uint8 data) { mmio.va = (mmio.va & 0xffff00) | (data << 0); }
368
void SA1::mmio_w225a(uint8 data) { mmio.va = (mmio.va & 0xff00ff) | (data << 8); }
369
void SA1::mmio_w225b(uint8 data) { mmio.va = (mmio.va & 0x00ffff) | (data << 16); mmio.vbit = 0; }
370
371
//(SFR) S-CPU flag read
372
uint8 SA1::mmio_r2300() {
373
uint8 data;
374
data = mmio.cpu_irqfl << 7;
375
data |= mmio.cpu_ivsw << 6;
376
data |= mmio.chdma_irqfl << 5;
377
data |= mmio.cpu_nvsw << 4;
378
data |= mmio.cmeg;
379
return data;
380
}
381
382
//(CFR) SA-1 flag read
383
uint8 SA1::mmio_r2301() {
384
uint8 data;
385
data = mmio.sa1_irqfl << 7;
386
data |= mmio.timer_irqfl << 6;
387
data |= mmio.dma_irqfl << 5;
388
data |= mmio.sa1_nmifl << 4;
389
data |= mmio.smeg;
390
return data;
391
}
392
393
//(HCR) hcounter read
394
uint8 SA1::mmio_r2302() {
395
//latch counters
396
mmio.hcr = status.hcounter >> 2;
397
mmio.vcr = status.vcounter;
398
return mmio.hcr >> 0; }
399
uint8 SA1::mmio_r2303() { return mmio.hcr >> 8; }
400
401
//(VCR) vcounter read
402
uint8 SA1::mmio_r2304() { return mmio.vcr >> 0; }
403
uint8 SA1::mmio_r2305() { return mmio.vcr >> 8; }
404
405
//(MR) arithmetic result
406
uint8 SA1::mmio_r2306() { return mmio.mr >> 0; }
407
uint8 SA1::mmio_r2307() { return mmio.mr >> 8; }
408
uint8 SA1::mmio_r2308() { return mmio.mr >> 16; }
409
uint8 SA1::mmio_r2309() { return mmio.mr >> 24; }
410
uint8 SA1::mmio_r230a() { return mmio.mr >> 32; }
411
412
//(OF) arithmetic overflow flag
413
uint8 SA1::mmio_r230b() { return mmio.overflow << 7; }
414
415
//(VDPL) variable-length data read port low
416
uint8 SA1::mmio_r230c() {
417
uint32 data = (vbr_read(mmio.va + 0) << 0)
418
| (vbr_read(mmio.va + 1) << 8)
419
| (vbr_read(mmio.va + 2) << 16);
420
data >>= mmio.vbit;
421
return data >> 0;
422
}
423
424
//(VDPH) variable-length data read port high
425
uint8 SA1::mmio_r230d() {
426
uint32 data = (vbr_read(mmio.va + 0) << 0)
427
| (vbr_read(mmio.va + 1) << 8)
428
| (vbr_read(mmio.va + 2) << 16);
429
data >>= mmio.vbit;
430
431
if(mmio.hl == 1) {
432
//auto-increment mode
433
mmio.vbit += mmio.vb;
434
mmio.va += (mmio.vbit >> 3);
435
mmio.vbit &= 7;
436
}
437
438
return data >> 8;
439
}
440
441
//(VC) version code register
442
uint8 SA1::mmio_r230e() {
443
return 0x01; //true value unknown
444
}
445
446
uint8 SA1::mmio_read(unsigned addr) {
447
(co_active() == cpu.thread ? cpu.synchronize_coprocessors() : synchronize_cpu());
448
addr &= 0xffff;
449
450
switch(addr) {
451
case 0x2300: return mmio_r2300();
452
case 0x2301: return mmio_r2301();
453
case 0x2302: return mmio_r2302();
454
case 0x2303: return mmio_r2303();
455
case 0x2304: return mmio_r2304();
456
case 0x2305: return mmio_r2305();
457
case 0x2306: return mmio_r2306();
458
case 0x2307: return mmio_r2307();
459
case 0x2308: return mmio_r2308();
460
case 0x2309: return mmio_r2309();
461
case 0x230a: return mmio_r230a();
462
case 0x230b: return mmio_r230b();
463
case 0x230c: return mmio_r230c();
464
case 0x230d: return mmio_r230d();
465
case 0x230e: return mmio_r230e();
466
}
467
468
return 0x00;
469
}
470
471
void SA1::mmio_write(unsigned addr, uint8 data) {
472
(co_active() == cpu.thread ? cpu.synchronize_coprocessors() : synchronize_cpu());
473
addr &= 0xffff;
474
475
switch(addr) {
476
case 0x2200: return mmio_w2200(data);
477
case 0x2201: return mmio_w2201(data);
478
case 0x2202: return mmio_w2202(data);
479
case 0x2203: return mmio_w2203(data);
480
case 0x2204: return mmio_w2204(data);
481
case 0x2205: return mmio_w2205(data);
482
case 0x2206: return mmio_w2206(data);
483
case 0x2207: return mmio_w2207(data);
484
case 0x2208: return mmio_w2208(data);
485
case 0x2209: return mmio_w2209(data);
486
case 0x220a: return mmio_w220a(data);
487
case 0x220b: return mmio_w220b(data);
488
case 0x220c: return mmio_w220c(data);
489
case 0x220d: return mmio_w220d(data);
490
case 0x220e: return mmio_w220e(data);
491
case 0x220f: return mmio_w220f(data);
492
493
case 0x2210: return mmio_w2210(data);
494
case 0x2211: return mmio_w2211(data);
495
case 0x2212: return mmio_w2212(data);
496
case 0x2213: return mmio_w2213(data);
497
case 0x2214: return mmio_w2214(data);
498
case 0x2215: return mmio_w2215(data);
499
500
case 0x2220: return mmio_w2220(data);
501
case 0x2221: return mmio_w2221(data);
502
case 0x2222: return mmio_w2222(data);
503
case 0x2223: return mmio_w2223(data);
504
case 0x2224: return mmio_w2224(data);
505
case 0x2225: return mmio_w2225(data);
506
case 0x2226: return mmio_w2226(data);
507
case 0x2227: return mmio_w2227(data);
508
case 0x2228: return mmio_w2228(data);
509
case 0x2229: return mmio_w2229(data);
510
case 0x222a: return mmio_w222a(data);
511
512
case 0x2230: return mmio_w2230(data);
513
case 0x2231: return mmio_w2231(data);
514
case 0x2232: return mmio_w2232(data);
515
case 0x2233: return mmio_w2233(data);
516
case 0x2234: return mmio_w2234(data);
517
case 0x2235: return mmio_w2235(data);
518
case 0x2236: return mmio_w2236(data);
519
case 0x2237: return mmio_w2237(data);
520
case 0x2238: return mmio_w2238(data);
521
case 0x2239: return mmio_w2239(data);
522
523
case 0x223f: return mmio_w223f(data);
524
case 0x2240: return mmio_w2240(data);
525
case 0x2241: return mmio_w2241(data);
526
case 0x2242: return mmio_w2242(data);
527
case 0x2243: return mmio_w2243(data);
528
case 0x2244: return mmio_w2244(data);
529
case 0x2245: return mmio_w2245(data);
530
case 0x2246: return mmio_w2246(data);
531
case 0x2247: return mmio_w2247(data);
532
case 0x2248: return mmio_w2248(data);
533
case 0x2249: return mmio_w2249(data);
534
case 0x224a: return mmio_w224a(data);
535
case 0x224b: return mmio_w224b(data);
536
case 0x224c: return mmio_w224c(data);
537
case 0x224d: return mmio_w224d(data);
538
case 0x224e: return mmio_w224e(data);
539
case 0x224f: return mmio_w224f(data);
540
541
case 0x2250: return mmio_w2250(data);
542
case 0x2251: return mmio_w2251(data);
543
case 0x2252: return mmio_w2252(data);
544
case 0x2253: return mmio_w2253(data);
545
case 0x2254: return mmio_w2254(data);
546
547
case 0x2258: return mmio_w2258(data);
548
case 0x2259: return mmio_w2259(data);
549
case 0x225a: return mmio_w225a(data);
550
case 0x225b: return mmio_w225b(data);
551
}
552
}
553
554
#endif
555
556