Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.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
uint16 PPU::get_vram_address() {
10
uint16 addr = regs.vram_addr;
11
switch(regs.vram_mapping) {
12
case 0: break; //direct mapping
13
case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break;
14
case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break;
15
case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break;
16
}
17
return (addr << 1);
18
}
19
20
//NOTE: all VRAM writes during active display are invalid. Unlike OAM and CGRAM, they will
21
//not be written anywhere at all. The below address ranges for where writes are invalid have
22
//been validated on hardware, as has the edge case where the S-CPU MDR can be written if the
23
//write occurs during the very last clock cycle of vblank.
24
25
uint8 PPU::vram_mmio_read(uint16 addr) {
26
uint8 data;
27
28
if(regs.display_disabled == true) {
29
data = vram[addr];
30
} else {
31
uint16 v = cpu.vcounter();
32
uint16 h = cpu.hcounter();
33
uint16 ls = ((system.region() == System::Region::NTSC ? 525 : 625) >> 1) - 1;
34
if(interlace() && !cpu.field()) ls++;
35
36
if(v == ls && h == 1362) {
37
data = 0x00;
38
} else if(v < (!overscan() ? 224 : 239)) {
39
data = 0x00;
40
} else if(v == (!overscan() ? 224 : 239)) {
41
if(h == 1362) {
42
data = vram[addr];
43
} else {
44
data = 0x00;
45
}
46
} else {
47
data = vram[addr];
48
}
49
}
50
51
return data;
52
}
53
54
void PPU::vram_mmio_write(uint16 addr, uint8 data) {
55
if(regs.display_disabled == true) {
56
vram[addr] = data;
57
} else {
58
uint16 v = cpu.vcounter();
59
uint16 h = cpu.hcounter();
60
if(v == 0) {
61
if(h <= 4) {
62
vram[addr] = data;
63
} else if(h == 6) {
64
vram[addr] = cpu.regs.mdr;
65
} else {
66
//no write
67
}
68
} else if(v < (!overscan() ? 225 : 240)) {
69
//no write
70
} else if(v == (!overscan() ? 225 : 240)) {
71
if(h <= 4) {
72
//no write
73
} else {
74
vram[addr] = data;
75
}
76
} else {
77
vram[addr] = data;
78
}
79
}
80
}
81
82
uint8 PPU::oam_mmio_read(uint16 addr) {
83
addr &= 0x03ff;
84
if(addr & 0x0200) addr &= 0x021f;
85
uint8 data;
86
87
if(regs.display_disabled == true) {
88
data = oam[addr];
89
} else {
90
if(cpu.vcounter() < (!overscan() ? 225 : 240)) {
91
data = oam[regs.ioamaddr];
92
} else {
93
data = oam[addr];
94
}
95
}
96
97
return data;
98
}
99
100
void PPU::oam_mmio_write(uint16 addr, uint8 data) {
101
addr &= 0x03ff;
102
if(addr & 0x0200) addr &= 0x021f;
103
104
sprite_list_valid = false;
105
106
if(regs.display_disabled == true) {
107
oam[addr] = data;
108
update_sprite_list(addr, data);
109
} else {
110
if(cpu.vcounter() < (!overscan() ? 225 : 240)) {
111
oam[regs.ioamaddr] = data;
112
update_sprite_list(regs.ioamaddr, data);
113
} else {
114
oam[addr] = data;
115
update_sprite_list(addr, data);
116
}
117
}
118
}
119
120
uint8 PPU::cgram_mmio_read(uint16 addr) {
121
addr &= 0x01ff;
122
uint8 data;
123
124
if(1 || regs.display_disabled == true) {
125
data = cgram[addr];
126
} else {
127
uint16 v = cpu.vcounter();
128
uint16 h = cpu.hcounter();
129
if(v < (!overscan() ? 225 : 240) && h >= 128 && h < 1096) {
130
data = cgram[regs.icgramaddr] & 0x7f;
131
} else {
132
data = cgram[addr];
133
}
134
}
135
136
if(addr & 1) data &= 0x7f;
137
return data;
138
}
139
140
void PPU::cgram_mmio_write(uint16 addr, uint8 data) {
141
addr &= 0x01ff;
142
if(addr & 1) data &= 0x7f;
143
144
if(1 || regs.display_disabled == true) {
145
cgram[addr] = data;
146
} else {
147
uint16 v = cpu.vcounter();
148
uint16 h = cpu.hcounter();
149
if(v < (!overscan() ? 225 : 240) && h >= 128 && h < 1096) {
150
cgram[regs.icgramaddr] = data & 0x7f;
151
} else {
152
cgram[addr] = data;
153
}
154
}
155
}
156
157
#endif
158
159