Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp
2 views
1
#ifdef PPU_CPP
2
3
void PPU::latch_counters() {
4
regs.hcounter = cpu.hdot();
5
regs.vcounter = cpu.vcounter();
6
regs.counters_latched = true;
7
}
8
9
bool PPU::interlace() const { return display.interlace; }
10
bool PPU::overscan() const { return display.overscan; }
11
bool PPU::hires() const { return regs.pseudo_hires || regs.bgmode == 5 || regs.bgmode == 6; }
12
13
uint16 PPU::get_vram_addr() {
14
uint16 addr = regs.vram_addr;
15
switch(regs.vram_mapping) {
16
case 0: break;
17
case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break;
18
case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break;
19
case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break;
20
}
21
return (addr << 1);
22
}
23
24
uint8 PPU::vram_read(unsigned addr) {
25
if(regs.display_disable) return vram[addr];
26
if(cpu.vcounter() >= display.height) return vram[addr];
27
return 0x00;
28
}
29
30
void PPU::vram_write(unsigned addr, uint8 data) {
31
if(regs.display_disable || cpu.vcounter() >= display.height) {
32
vram[addr] = data;
33
cache.tilevalid[0][addr >> 4] = false;
34
cache.tilevalid[1][addr >> 5] = false;
35
cache.tilevalid[2][addr >> 6] = false;
36
return;
37
}
38
}
39
40
uint8 PPU::oam_read(unsigned addr) {
41
if(addr & 0x0200) addr &= 0x021f;
42
if(regs.display_disable) return oam[addr];
43
if(cpu.vcounter() >= display.height) return oam[addr];
44
return oam[0x0218];
45
}
46
47
void PPU::oam_write(unsigned addr, uint8 data) {
48
if(addr & 0x0200) addr &= 0x021f;
49
if(!regs.display_disable && cpu.vcounter() < display.height) addr = 0x0218;
50
oam[addr] = data;
51
sprite.update_list(addr, data);
52
}
53
54
uint8 PPU::cgram_read(unsigned addr) {
55
return cgram[addr];
56
}
57
58
void PPU::cgram_write(unsigned addr, uint8 data) {
59
cgram[addr] = data;
60
}
61
62
void PPU::mmio_update_video_mode() {
63
switch(regs.bgmode) {
64
case 0: {
65
bg1.regs.mode = Background::Mode::BPP2; bg1.regs.priority0 = 8; bg1.regs.priority1 = 11;
66
bg2.regs.mode = Background::Mode::BPP2; bg2.regs.priority0 = 7; bg2.regs.priority1 = 10;
67
bg3.regs.mode = Background::Mode::BPP2; bg3.regs.priority0 = 2; bg3.regs.priority1 = 5;
68
bg4.regs.mode = Background::Mode::BPP2; bg4.regs.priority0 = 1; bg4.regs.priority1 = 4;
69
sprite.regs.priority0 = 3; sprite.regs.priority1 = 6; sprite.regs.priority2 = 9; sprite.regs.priority3 = 12;
70
} break;
71
72
case 1: {
73
bg1.regs.mode = Background::Mode::BPP4;
74
bg2.regs.mode = Background::Mode::BPP4;
75
bg3.regs.mode = Background::Mode::BPP2;
76
bg4.regs.mode = Background::Mode::Inactive;
77
if(regs.bg3_priority) {
78
bg1.regs.priority0 = 5; bg1.regs.priority1 = 8;
79
bg2.regs.priority0 = 4; bg2.regs.priority1 = 7;
80
bg3.regs.priority0 = 1; bg3.regs.priority1 = 10;
81
sprite.regs.priority0 = 2; sprite.regs.priority1 = 3; sprite.regs.priority2 = 6; sprite.regs.priority3 = 9;
82
} else {
83
bg1.regs.priority0 = 6; bg1.regs.priority1 = 9;
84
bg2.regs.priority0 = 5; bg2.regs.priority1 = 8;
85
bg3.regs.priority0 = 1; bg3.regs.priority1 = 3;
86
sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 7; sprite.regs.priority3 = 10;
87
}
88
} break;
89
90
case 2: {
91
bg1.regs.mode = Background::Mode::BPP4;
92
bg2.regs.mode = Background::Mode::BPP4;
93
bg3.regs.mode = Background::Mode::Inactive;
94
bg4.regs.mode = Background::Mode::Inactive;
95
bg1.regs.priority0 = 3; bg1.regs.priority1 = 7;
96
bg2.regs.priority0 = 1; bg2.regs.priority1 = 5;
97
sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8;
98
} break;
99
100
case 3: {
101
bg1.regs.mode = Background::Mode::BPP8;
102
bg2.regs.mode = Background::Mode::BPP4;
103
bg3.regs.mode = Background::Mode::Inactive;
104
bg4.regs.mode = Background::Mode::Inactive;
105
bg1.regs.priority0 = 3; bg1.regs.priority1 = 7;
106
bg2.regs.priority0 = 1; bg2.regs.priority1 = 5;
107
sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8;
108
} break;
109
110
case 4: {
111
bg1.regs.mode = Background::Mode::BPP8;
112
bg2.regs.mode = Background::Mode::BPP2;
113
bg3.regs.mode = Background::Mode::Inactive;
114
bg4.regs.mode = Background::Mode::Inactive;
115
bg1.regs.priority0 = 3; bg1.regs.priority1 = 7;
116
bg2.regs.priority0 = 1; bg2.regs.priority1 = 5;
117
sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8;
118
} break;
119
120
case 5: {
121
bg1.regs.mode = Background::Mode::BPP4;
122
bg2.regs.mode = Background::Mode::BPP2;
123
bg3.regs.mode = Background::Mode::Inactive;
124
bg4.regs.mode = Background::Mode::Inactive;
125
bg1.regs.priority0 = 3; bg1.regs.priority1 = 7;
126
bg2.regs.priority0 = 1; bg2.regs.priority1 = 5;
127
sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 8;
128
} break;
129
130
case 6: {
131
bg1.regs.mode = Background::Mode::BPP4;
132
bg2.regs.mode = Background::Mode::Inactive;
133
bg3.regs.mode = Background::Mode::Inactive;
134
bg4.regs.mode = Background::Mode::Inactive;
135
bg1.regs.priority0 = 2; bg1.regs.priority1 = 5;
136
sprite.regs.priority0 = 1; sprite.regs.priority1 = 3; sprite.regs.priority2 = 4; sprite.regs.priority3 = 6;
137
} break;
138
139
case 7: {
140
if(regs.mode7_extbg == false) {
141
bg1.regs.mode = Background::Mode::Mode7;
142
bg2.regs.mode = Background::Mode::Inactive;
143
bg3.regs.mode = Background::Mode::Inactive;
144
bg4.regs.mode = Background::Mode::Inactive;
145
bg1.regs.priority0 = 2; bg1.regs.priority1 = 2;
146
sprite.regs.priority0 = 1; sprite.regs.priority1 = 3; sprite.regs.priority2 = 4; sprite.regs.priority3 = 5;
147
} else {
148
bg1.regs.mode = Background::Mode::Mode7;
149
bg2.regs.mode = Background::Mode::Mode7;
150
bg3.regs.mode = Background::Mode::Inactive;
151
bg4.regs.mode = Background::Mode::Inactive;
152
bg1.regs.priority0 = 3; bg1.regs.priority1 = 3;
153
bg2.regs.priority0 = 1; bg2.regs.priority1 = 5;
154
sprite.regs.priority0 = 2; sprite.regs.priority1 = 4; sprite.regs.priority2 = 6; sprite.regs.priority3 = 7;
155
}
156
} break;
157
}
158
}
159
160
uint8 PPU::mmio_read(unsigned addr) {
161
cpu.synchronize_ppu();
162
163
switch(addr & 0xffff) {
164
case 0x2104: case 0x2105: case 0x2106: case 0x2108: case 0x2109: case 0x210a:
165
case 0x2114: case 0x2115: case 0x2116: case 0x2118: case 0x2119: case 0x211a:
166
case 0x2124: case 0x2125: case 0x2126: case 0x2128: case 0x2129: case 0x212a: {
167
return regs.ppu1_mdr;
168
}
169
170
case 0x2134: { //MPYL
171
unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
172
regs.ppu1_mdr = result >> 0;
173
return regs.ppu1_mdr;
174
}
175
176
case 0x2135: { //MPYM
177
unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
178
regs.ppu1_mdr = result >> 8;
179
return regs.ppu1_mdr;
180
}
181
182
case 0x2136: { //MPYH
183
unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
184
regs.ppu1_mdr = result >> 16;
185
return regs.ppu1_mdr;
186
}
187
188
case 0x2137: { //SLHV
189
if(cpu.pio() & 0x80) latch_counters();
190
return cpu.regs.mdr;
191
}
192
193
case 0x2138: { //OAMDATAREAD
194
regs.ppu1_mdr = oam_read(regs.oam_addr);
195
regs.oam_addr = (regs.oam_addr + 1) & 0x03ff;
196
sprite.set_first();
197
return regs.ppu1_mdr;
198
}
199
200
case 0x2139: { //VMDATALREAD
201
regs.ppu1_mdr = regs.vram_readbuffer >> 0;
202
if(regs.vram_incmode == 0) {
203
uint16 addr = get_vram_addr();
204
regs.vram_readbuffer = vram_read(addr + 0) << 0;
205
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
206
regs.vram_addr += regs.vram_incsize;
207
}
208
return regs.ppu1_mdr;
209
}
210
211
case 0x213a: { //VMDATAHREAD
212
regs.ppu1_mdr = regs.vram_readbuffer >> 8;
213
if(regs.vram_incmode == 1) {
214
uint16 addr = get_vram_addr();
215
regs.vram_readbuffer = vram_read(addr + 0) << 0;
216
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
217
regs.vram_addr += regs.vram_incsize;
218
}
219
return regs.ppu1_mdr;
220
}
221
222
case 0x213b: { //CGDATAREAD
223
if((regs.cgram_addr & 1) == 0) {
224
regs.ppu2_mdr = cgram_read(regs.cgram_addr);
225
} else {
226
regs.ppu2_mdr = (regs.ppu2_mdr & 0x80) | (cgram_read(regs.cgram_addr) & 0x7f);
227
}
228
regs.cgram_addr = (regs.cgram_addr + 1) & 0x01ff;
229
return regs.ppu2_mdr;
230
}
231
232
case 0x213c: { //OPHCT
233
if(regs.latch_hcounter == 0) {
234
regs.ppu2_mdr = regs.hcounter & 0xff;
235
} else {
236
regs.ppu2_mdr = (regs.ppu2_mdr & 0xfe) | (regs.hcounter >> 8);
237
}
238
regs.latch_hcounter ^= 1;
239
return regs.ppu2_mdr;
240
}
241
242
case 0x213d: { //OPVCT
243
if(regs.latch_vcounter == 0) {
244
regs.ppu2_mdr = regs.vcounter & 0xff;
245
} else {
246
regs.ppu2_mdr = (regs.ppu2_mdr & 0xfe) | (regs.vcounter >> 8);
247
}
248
regs.latch_vcounter ^= 1;
249
return regs.ppu2_mdr;
250
}
251
252
case 0x213e: { //STAT77
253
regs.ppu1_mdr &= 0x10;
254
regs.ppu1_mdr |= sprite.regs.time_over << 7;
255
regs.ppu1_mdr |= sprite.regs.range_over << 6;
256
regs.ppu1_mdr |= 0x01; //version
257
return regs.ppu1_mdr;
258
}
259
260
case 0x213f: { //STAT78
261
regs.latch_hcounter = 0;
262
regs.latch_vcounter = 0;
263
264
regs.ppu2_mdr &= 0x20;
265
regs.ppu2_mdr |= cpu.field() << 7;
266
if((cpu.pio() & 0x80) == 0) {
267
regs.ppu2_mdr |= 0x40;
268
} else if(regs.counters_latched) {
269
regs.ppu2_mdr |= 0x40;
270
regs.counters_latched = false;
271
}
272
regs.ppu2_mdr |= (system.region() == System::Region::NTSC ? 0 : 1) << 4;
273
regs.ppu2_mdr |= 0x03; //version
274
return regs.ppu2_mdr;
275
}
276
}
277
278
return cpu.regs.mdr;
279
}
280
281
void PPU::mmio_write(unsigned addr, uint8 data) {
282
cpu.synchronize_ppu();
283
284
switch(addr & 0xffff) {
285
case 0x2100: { //INIDISP
286
if(regs.display_disable && cpu.vcounter() == display.height) sprite.address_reset();
287
regs.display_disable = data & 0x80;
288
regs.display_brightness = data & 0x0f;
289
return;
290
}
291
292
case 0x2101: { //OBSEL
293
sprite.regs.base_size = (data >> 5) & 7;
294
sprite.regs.nameselect = (data >> 3) & 3;
295
sprite.regs.tiledata_addr = (data & 3) << 14;
296
sprite.list_valid = false;
297
return;
298
}
299
300
case 0x2102: { //OAMADDL
301
regs.oam_baseaddr = (regs.oam_baseaddr & 0x0100) | (data << 0);
302
sprite.address_reset();
303
return;
304
}
305
306
case 0x2103: { //OAMADDH
307
regs.oam_priority = data & 0x80;
308
regs.oam_baseaddr = ((data & 1) << 8) | (regs.oam_baseaddr & 0x00ff);
309
sprite.address_reset();
310
return;
311
}
312
313
case 0x2104: { //OAMDATA
314
if((regs.oam_addr & 1) == 0) regs.oam_latchdata = data;
315
if(regs.oam_addr & 0x0200) {
316
oam_write(regs.oam_addr, data);
317
} else if((regs.oam_addr & 1) == 1) {
318
oam_write((regs.oam_addr & ~1) + 0, regs.oam_latchdata);
319
oam_write((regs.oam_addr & ~1) + 1, data);
320
}
321
regs.oam_addr = (regs.oam_addr + 1) & 0x03ff;
322
sprite.set_first();
323
return;
324
}
325
326
case 0x2105: { //BGMODE
327
bg4.regs.tile_size = data & 0x80;
328
bg3.regs.tile_size = data & 0x40;
329
bg2.regs.tile_size = data & 0x20;
330
bg1.regs.tile_size = data & 0x10;
331
regs.bg3_priority = data & 0x08;
332
regs.bgmode = data & 0x07;
333
mmio_update_video_mode();
334
return;
335
}
336
337
case 0x2106: { //MOSAIC
338
unsigned mosaic_size = (data >> 4) & 15;
339
bg4.regs.mosaic = (data & 0x08 ? mosaic_size : 0);
340
bg3.regs.mosaic = (data & 0x04 ? mosaic_size : 0);
341
bg2.regs.mosaic = (data & 0x02 ? mosaic_size : 0);
342
bg1.regs.mosaic = (data & 0x01 ? mosaic_size : 0);
343
return;
344
}
345
346
case 0x2107: { //BG1SC
347
bg1.regs.screen_addr = (data & 0x7c) << 9;
348
bg1.regs.screen_size = data & 3;
349
return;
350
}
351
352
case 0x2108: { //BG2SC
353
bg2.regs.screen_addr = (data & 0x7c) << 9;
354
bg2.regs.screen_size = data & 3;
355
return;
356
}
357
358
case 0x2109: { //BG3SC
359
bg3.regs.screen_addr = (data & 0x7c) << 9;
360
bg3.regs.screen_size = data & 3;
361
return;
362
}
363
364
case 0x210a: { //BG4SC
365
bg4.regs.screen_addr = (data & 0x7c) << 9;
366
bg4.regs.screen_size = data & 3;
367
return;
368
}
369
370
case 0x210b: { //BG12NBA
371
bg1.regs.tiledata_addr = (data & 0x07) << 13;
372
bg2.regs.tiledata_addr = (data & 0x70) << 9;
373
return;
374
}
375
376
case 0x210c: { //BG34NBA
377
bg3.regs.tiledata_addr = (data & 0x07) << 13;
378
bg4.regs.tiledata_addr = (data & 0x70) << 9;
379
return;
380
}
381
382
case 0x210d: { //BG1HOFS
383
regs.mode7_hoffset = (data << 8) | regs.mode7_latchdata;
384
regs.mode7_latchdata = data;
385
386
bg1.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg1.regs.hoffset >> 8) & 7);
387
regs.bgofs_latchdata = data;
388
return;
389
}
390
391
case 0x210e: { //BG1VOFS
392
regs.mode7_voffset = (data << 8) | regs.mode7_latchdata;
393
regs.mode7_latchdata = data;
394
395
bg1.regs.voffset = (data << 8) | regs.bgofs_latchdata;
396
regs.bgofs_latchdata = data;
397
return;
398
}
399
400
case 0x210f: { //BG2HOFS
401
bg2.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg2.regs.hoffset >> 8) & 7);
402
regs.bgofs_latchdata = data;
403
return;
404
}
405
406
case 0x2110: { //BG2VOFS
407
bg2.regs.voffset = (data << 8) | regs.bgofs_latchdata;
408
regs.bgofs_latchdata = data;
409
return;
410
}
411
412
case 0x2111: { //BG3HOFS
413
bg3.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg3.regs.hoffset >> 8) & 7);
414
regs.bgofs_latchdata = data;
415
return;
416
}
417
418
case 0x2112: { //BG3VOFS
419
bg3.regs.voffset = (data << 8) | regs.bgofs_latchdata;
420
regs.bgofs_latchdata = data;
421
return;
422
}
423
424
case 0x2113: { //BG4HOFS
425
bg4.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg4.regs.hoffset >> 8) & 7);
426
regs.bgofs_latchdata = data;
427
return;
428
}
429
430
case 0x2114: { //BG4VOFS
431
bg4.regs.voffset = (data << 8) | regs.bgofs_latchdata;
432
regs.bgofs_latchdata = data;
433
return;
434
}
435
436
case 0x2115: { //VMAIN
437
regs.vram_incmode = data & 0x80;
438
regs.vram_mapping = (data >> 2) & 3;
439
switch(data & 3) {
440
case 0: regs.vram_incsize = 1; break;
441
case 1: regs.vram_incsize = 32; break;
442
case 2: regs.vram_incsize = 128; break;
443
case 3: regs.vram_incsize = 128; break;
444
}
445
return;
446
}
447
448
case 0x2116: { //VMADDL
449
regs.vram_addr = (regs.vram_addr & 0xff00) | (data << 0);
450
uint16 addr = get_vram_addr();
451
regs.vram_readbuffer = vram_read(addr + 0) << 0;
452
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
453
return;
454
}
455
456
case 0x2117: { //VMADDH
457
regs.vram_addr = (data << 8) | (regs.vram_addr & 0x00ff);
458
uint16 addr = get_vram_addr();
459
regs.vram_readbuffer = vram_read(addr + 0) << 0;
460
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
461
return;
462
}
463
464
case 0x2118: { //VMDATAL
465
vram_write(get_vram_addr() + 0, data);
466
if(regs.vram_incmode == 0) regs.vram_addr += regs.vram_incsize;
467
return;
468
}
469
470
case 0x2119: { //VMDATAH
471
vram_write(get_vram_addr() + 1, data);
472
if(regs.vram_incmode == 1) regs.vram_addr += regs.vram_incsize;
473
return;
474
}
475
476
case 0x211a: { //M7SEL
477
regs.mode7_repeat = (data >> 6) & 3;
478
regs.mode7_vflip = data & 0x02;
479
regs.mode7_hflip = data & 0x01;
480
return;
481
}
482
483
case 0x211b: { //M7A
484
regs.m7a = (data << 8) | regs.mode7_latchdata;
485
regs.mode7_latchdata = data;
486
return;
487
}
488
489
case 0x211c: { //M7B
490
regs.m7b = (data << 8) | regs.mode7_latchdata;
491
regs.mode7_latchdata = data;
492
return;
493
}
494
495
case 0x211d: { //M7C
496
regs.m7c = (data << 8) | regs.mode7_latchdata;
497
regs.mode7_latchdata = data;
498
return;
499
}
500
501
case 0x211e: { //M7D
502
regs.m7d = (data << 8) | regs.mode7_latchdata;
503
regs.mode7_latchdata = data;
504
return;
505
}
506
507
case 0x211f: { //M7X
508
regs.m7x = (data << 8) | regs.mode7_latchdata;
509
regs.mode7_latchdata = data;
510
return;
511
}
512
513
case 0x2120: { //M7Y
514
regs.m7y = (data << 8) | regs.mode7_latchdata;
515
regs.mode7_latchdata = data;
516
return;
517
}
518
519
case 0x2121: { //CGADD
520
regs.cgram_addr = data << 1;
521
return;
522
}
523
524
case 0x2122: { //CGDATA
525
if((regs.cgram_addr & 1) == 0) {
526
regs.cgram_latchdata = data;
527
} else {
528
cgram_write((regs.cgram_addr & ~1) + 0, regs.cgram_latchdata);
529
cgram_write((regs.cgram_addr & ~1) + 1, data & 0x7f);
530
}
531
regs.cgram_addr = (regs.cgram_addr + 1) & 0x01ff;
532
return;
533
}
534
535
case 0x2123: { //W12SEL
536
bg2.window.two_enable = data & 0x80;
537
bg2.window.two_invert = data & 0x40;
538
bg2.window.one_enable = data & 0x20;
539
bg2.window.one_invert = data & 0x10;
540
bg1.window.two_enable = data & 0x08;
541
bg1.window.two_invert = data & 0x04;
542
bg1.window.one_enable = data & 0x02;
543
bg1.window.one_invert = data & 0x01;
544
return;
545
}
546
547
case 0x2124: { //W34SEL
548
bg4.window.two_enable = data & 0x80;
549
bg4.window.two_invert = data & 0x40;
550
bg4.window.one_enable = data & 0x20;
551
bg4.window.one_invert = data & 0x10;
552
bg3.window.two_enable = data & 0x08;
553
bg3.window.two_invert = data & 0x04;
554
bg3.window.one_enable = data & 0x02;
555
bg3.window.one_invert = data & 0x01;
556
return;
557
}
558
559
case 0x2125: { //WOBJSEL
560
screen.window.two_enable = data & 0x80;
561
screen.window.two_invert = data & 0x40;
562
screen.window.one_enable = data & 0x20;
563
screen.window.one_invert = data & 0x10;
564
sprite.window.two_enable = data & 0x08;
565
sprite.window.two_invert = data & 0x04;
566
sprite.window.one_enable = data & 0x02;
567
sprite.window.one_invert = data & 0x01;
568
return;
569
}
570
571
case 0x2126: { //WH0
572
regs.window_one_left = data;
573
return;
574
}
575
576
case 0x2127: { //WH1
577
regs.window_one_right = data;
578
return;
579
}
580
581
case 0x2128: { //WH2
582
regs.window_two_left = data;
583
return;
584
}
585
586
case 0x2129: { //WH3
587
regs.window_two_right = data;
588
return;
589
}
590
591
case 0x212a: { //WBGLOG
592
bg4.window.mask = (data >> 6) & 3;
593
bg3.window.mask = (data >> 4) & 3;
594
bg2.window.mask = (data >> 2) & 3;
595
bg1.window.mask = (data >> 0) & 3;
596
return;
597
}
598
599
case 0x212b: { //WOBJLOG
600
screen.window.mask = (data >> 2) & 3;
601
sprite.window.mask = (data >> 0) & 3;
602
return;
603
}
604
605
case 0x212c: { //TM
606
sprite.regs.main_enable = data & 0x10;
607
bg4.regs.main_enable = data & 0x08;
608
bg3.regs.main_enable = data & 0x04;
609
bg2.regs.main_enable = data & 0x02;
610
bg1.regs.main_enable = data & 0x01;
611
return;
612
}
613
614
case 0x212d: { //TS
615
sprite.regs.sub_enable = data & 0x10;
616
bg4.regs.sub_enable = data & 0x08;
617
bg3.regs.sub_enable = data & 0x04;
618
bg2.regs.sub_enable = data & 0x02;
619
bg1.regs.sub_enable = data & 0x01;
620
return;
621
}
622
623
case 0x212e: { //TMW
624
sprite.window.main_enable = data & 0x10;
625
bg4.window.main_enable = data & 0x08;
626
bg3.window.main_enable = data & 0x04;
627
bg2.window.main_enable = data & 0x02;
628
bg1.window.main_enable = data & 0x01;
629
return;
630
}
631
632
case 0x212f: { //TSW
633
sprite.window.sub_enable = data & 0x10;
634
bg4.window.sub_enable = data & 0x08;
635
bg3.window.sub_enable = data & 0x04;
636
bg2.window.sub_enable = data & 0x02;
637
bg1.window.sub_enable = data & 0x01;
638
return;
639
}
640
641
case 0x2130: { //CGWSEL
642
screen.window.main_mask = (data >> 6) & 3;
643
screen.window.sub_mask = (data >> 4) & 3;
644
screen.regs.addsub_mode = data & 0x02;
645
screen.regs.direct_color = data & 0x01;
646
return;
647
}
648
649
case 0x2131: { //CGADDSUB
650
screen.regs.color_mode = data & 0x80;
651
screen.regs.color_halve = data & 0x40;
652
screen.regs.color_enable[6] = data & 0x20;
653
screen.regs.color_enable[5] = data & 0x10;
654
screen.regs.color_enable[4] = data & 0x10;
655
screen.regs.color_enable[3] = data & 0x08;
656
screen.regs.color_enable[2] = data & 0x04;
657
screen.regs.color_enable[1] = data & 0x02;
658
screen.regs.color_enable[0] = data & 0x01;
659
return;
660
}
661
662
case 0x2132: { //COLDATA
663
if(data & 0x80) screen.regs.color_b = data & 0x1f;
664
if(data & 0x40) screen.regs.color_g = data & 0x1f;
665
if(data & 0x20) screen.regs.color_r = data & 0x1f;
666
screen.regs.color = (screen.regs.color_b << 10) | (screen.regs.color_g << 5) | (screen.regs.color_r << 0);
667
return;
668
}
669
670
case 0x2133: { //SETINI
671
regs.mode7_extbg = data & 0x40;
672
regs.pseudo_hires = data & 0x08;
673
regs.overscan = data & 0x04;
674
sprite.regs.interlace = data & 0x02;
675
regs.interlace = data & 0x01;
676
mmio_update_video_mode();
677
sprite.list_valid = false;
678
return;
679
}
680
}
681
}
682
683
void PPU::mmio_reset() {
684
//internal
685
regs.ppu1_mdr = 0;
686
regs.ppu2_mdr = 0;
687
688
regs.vram_readbuffer = 0;
689
regs.oam_latchdata = 0;
690
regs.cgram_latchdata = 0;
691
regs.bgofs_latchdata = 0;
692
regs.mode7_latchdata = 0;
693
694
regs.counters_latched = 0;
695
regs.latch_hcounter = 0;
696
regs.latch_vcounter = 0;
697
698
sprite.regs.first_sprite = 0;
699
sprite.list_valid = false;
700
701
//$2100
702
regs.display_disable = true;
703
regs.display_brightness = 0;
704
705
//$2101
706
sprite.regs.base_size = 0;
707
sprite.regs.nameselect = 0;
708
sprite.regs.tiledata_addr = 0;
709
710
//$2102-$2103
711
regs.oam_baseaddr = 0;
712
regs.oam_addr = 0;
713
regs.oam_priority = 0;
714
715
//$2105
716
bg4.regs.tile_size = 0;
717
bg3.regs.tile_size = 0;
718
bg2.regs.tile_size = 0;
719
bg1.regs.tile_size = 0;
720
regs.bg3_priority = 0;
721
regs.bgmode = 0;
722
723
//$2106
724
bg4.regs.mosaic = 0;
725
bg3.regs.mosaic = 0;
726
bg2.regs.mosaic = 0;
727
bg1.regs.mosaic = 0;
728
729
//$2107-$210a
730
bg1.regs.screen_addr = 0;
731
bg1.regs.screen_size = 0;
732
bg2.regs.screen_addr = 0;
733
bg2.regs.screen_size = 0;
734
bg3.regs.screen_addr = 0;
735
bg3.regs.screen_size = 0;
736
bg4.regs.screen_addr = 0;
737
bg4.regs.screen_size = 0;
738
739
//$210b-$210c
740
bg1.regs.tiledata_addr = 0;
741
bg2.regs.tiledata_addr = 0;
742
bg3.regs.tiledata_addr = 0;
743
bg4.regs.tiledata_addr = 0;
744
745
//$210d-$2114
746
regs.mode7_hoffset = 0;
747
regs.mode7_voffset = 0;
748
bg1.regs.hoffset = 0;
749
bg1.regs.voffset = 0;
750
bg2.regs.hoffset = 0;
751
bg2.regs.voffset = 0;
752
bg3.regs.hoffset = 0;
753
bg3.regs.voffset = 0;
754
bg4.regs.hoffset = 0;
755
bg4.regs.voffset = 0;
756
757
//$2115
758
regs.vram_incmode = 0;
759
regs.vram_mapping = 0;
760
regs.vram_incsize = 1;
761
762
//$2116-$2117
763
regs.vram_addr = 0;
764
765
//$211a
766
regs.mode7_repeat = 0;
767
regs.mode7_vflip = 0;
768
regs.mode7_hflip = 0;
769
770
//$211b-$2120
771
regs.m7a = 0;
772
regs.m7b = 0;
773
regs.m7c = 0;
774
regs.m7d = 0;
775
regs.m7x = 0;
776
regs.m7y = 0;
777
778
//$2121
779
regs.cgram_addr = 0;
780
781
//$2123-$2125
782
bg1.window.one_enable = 0;
783
bg1.window.one_invert = 0;
784
bg1.window.two_enable = 0;
785
bg1.window.two_invert = 0;
786
787
bg2.window.one_enable = 0;
788
bg2.window.one_invert = 0;
789
bg2.window.two_enable = 0;
790
bg2.window.two_invert = 0;
791
792
bg3.window.one_enable = 0;
793
bg3.window.one_invert = 0;
794
bg3.window.two_enable = 0;
795
bg3.window.two_invert = 0;
796
797
bg4.window.one_enable = 0;
798
bg4.window.one_invert = 0;
799
bg4.window.two_enable = 0;
800
bg4.window.two_invert = 0;
801
802
sprite.window.one_enable = 0;
803
sprite.window.one_invert = 0;
804
sprite.window.two_enable = 0;
805
sprite.window.two_invert = 0;
806
807
screen.window.one_enable = 0;
808
screen.window.one_invert = 0;
809
screen.window.two_enable = 0;
810
screen.window.two_invert = 0;
811
812
//$2126-$2129
813
regs.window_one_left = 0;
814
regs.window_one_right = 0;
815
regs.window_two_left = 0;
816
regs.window_two_right = 0;
817
818
//$212a-$212b
819
bg1.window.mask = 0;
820
bg2.window.mask = 0;
821
bg3.window.mask = 0;
822
bg4.window.mask = 0;
823
sprite.window.mask = 0;
824
screen.window.mask = 0;
825
826
//$212c
827
bg1.regs.main_enable = 0;
828
bg2.regs.main_enable = 0;
829
bg3.regs.main_enable = 0;
830
bg4.regs.main_enable = 0;
831
sprite.regs.main_enable = 0;
832
833
//$212d
834
bg1.regs.sub_enable = 0;
835
bg2.regs.sub_enable = 0;
836
bg3.regs.sub_enable = 0;
837
bg4.regs.sub_enable = 0;
838
sprite.regs.sub_enable = 0;
839
840
//$212e
841
bg1.window.main_enable = 0;
842
bg2.window.main_enable = 0;
843
bg3.window.main_enable = 0;
844
bg4.window.main_enable = 0;
845
sprite.window.main_enable = 0;
846
847
//$212f
848
bg1.window.sub_enable = 0;
849
bg2.window.sub_enable = 0;
850
bg3.window.sub_enable = 0;
851
bg4.window.sub_enable = 0;
852
sprite.window.sub_enable = 0;
853
854
//$2130
855
screen.window.main_mask = 0;
856
screen.window.sub_mask = 0;
857
screen.regs.addsub_mode = 0;
858
screen.regs.direct_color = 0;
859
860
//$2131
861
screen.regs.color_mode = 0;
862
screen.regs.color_halve = 0;
863
screen.regs.color_enable[6] = 0;
864
screen.regs.color_enable[5] = 0;
865
screen.regs.color_enable[4] = 0;
866
screen.regs.color_enable[3] = 0;
867
screen.regs.color_enable[2] = 0;
868
screen.regs.color_enable[1] = 0;
869
screen.regs.color_enable[0] = 0;
870
871
//$2132
872
screen.regs.color_b = 0;
873
screen.regs.color_g = 0;
874
screen.regs.color_r = 0;
875
screen.regs.color = 0;
876
877
//$2133
878
regs.mode7_extbg = 0;
879
regs.pseudo_hires = 0;
880
regs.overscan = 0;
881
sprite.regs.interlace = 0;
882
regs.interlace = 0;
883
884
//$213e
885
sprite.regs.time_over = 0;
886
sprite.regs.range_over = 0;
887
888
mmio_update_video_mode();
889
}
890
891
#endif
892
893