Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/chip/sa1/memory/memory.cpp
2 views
1
#ifdef SA1_CPP
2
3
uint8 SA1::bus_read(unsigned addr) {
4
if((addr & 0x40fe00) == 0x002200) { //$00-3f|80-bf:2200-23ff
5
return mmio_read(addr);
6
}
7
8
if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff
9
return mmc_read(addr);
10
}
11
12
if((addr & 0xc00000) == 0xc00000) { //$c0-ff:0000-ffff
13
return mmc_read(addr);
14
}
15
16
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
17
return mmc_sa1_read(addr);
18
}
19
20
if((addr & 0x40f800) == 0x000000) { //$00-3f|80-bf:0000-07ff
21
synchronize_cpu();
22
return iram.read(addr & 2047);
23
}
24
25
if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff
26
synchronize_cpu();
27
return iram.read(addr & 2047);
28
}
29
30
if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff
31
synchronize_cpu();
32
return cartridge.ram.read(addr & (cartridge.ram.size() - 1));
33
}
34
35
if((addr & 0xf00000) == 0x600000) { //$60-6f:0000-ffff
36
synchronize_cpu();
37
return bitmap_read(addr & 0x0fffff);
38
}
39
}
40
41
void SA1::bus_write(unsigned addr, uint8 data) {
42
if((addr & 0x40fe00) == 0x002200) { //$00-3f|80-bf:2200-23ff
43
return mmio_write(addr, data);
44
}
45
46
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
47
return mmc_sa1_write(addr, data);
48
}
49
50
if((addr & 0x40f800) == 0x000000) { //$00-3f|80-bf:0000-07ff
51
synchronize_cpu();
52
return iram.write(addr & 2047, data);
53
}
54
55
if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff
56
synchronize_cpu();
57
return iram.write(addr & 2047, data);
58
}
59
60
if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff
61
synchronize_cpu();
62
return cartridge.ram.write(addr & (cartridge.ram.size() - 1), data);
63
}
64
65
if((addr & 0xf00000) == 0x600000) { //$60-6f:0000-ffff
66
synchronize_cpu();
67
return bitmap_write(addr & 0x0fffff, data);
68
}
69
}
70
71
//$230c (VDPL), $230d (VDPH) use this bus to read variable-length data.
72
//this is used both to keep VBR-reads from accessing MMIO registers, and
73
//to avoid syncing the S-CPU and SA-1*; as both chips are able to access
74
//these ports.
75
uint8 SA1::vbr_read(unsigned addr) {
76
if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff
77
return mmc_read(addr);
78
}
79
80
if((addr & 0xc00000) == 0xc00000) { //$c0-ff:0000-ffff
81
return mmc_read(addr);
82
}
83
84
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
85
return cartridge.ram.read(addr & (cartridge.ram.size() - 1));
86
}
87
88
if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff
89
return cartridge.ram.read(addr & (cartridge.ram.size() - 1));
90
}
91
92
if((addr & 0x40f800) == 0x000000) { //$00-3f|80-bf:0000-07ff
93
return iram.read(addr & 2047);
94
}
95
96
if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff
97
return iram.read(addr & 0x2047);
98
}
99
}
100
101
//ROM, I-RAM and MMIO registers are accessed at ~10.74MHz (2 clock ticks)
102
//BW-RAM is accessed at ~5.37MHz (4 clock ticks)
103
//tick() == 2 clock ticks
104
//note: bus conflict delays are not emulated at this time
105
106
void SA1::op_io() {
107
tick();
108
}
109
110
uint8 SA1::op_read(unsigned addr, eCDLog_Flags flags) {
111
(void)flags; //this was needed for inheritance purposes, as SA-1 is derived from the main CPU class
112
tick();
113
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
114
return bus_read(addr);
115
}
116
117
void SA1::op_write(unsigned addr, uint8 data) {
118
tick();
119
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
120
bus_write(addr, data);
121
}
122
123
uint8 SA1::mmc_read(unsigned addr) {
124
if((addr & 0xffffe0) == 0x00ffe0) {
125
if(addr == 0xffea && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 0;
126
if(addr == 0xffeb && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 8;
127
if(addr == 0xffee && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 0;
128
if(addr == 0xffef && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 8;
129
}
130
131
static auto read = [](unsigned addr) {
132
return cartridge.rom.read(bus.mirror(addr, cartridge.rom.size()));
133
};
134
135
if((addr & 0xe08000) == 0x008000) { //$00-1f:8000-ffff
136
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x007fff);
137
if(mmio.cbmode == 0) return read(0x000000 | addr);
138
return read((mmio.cb << 20) | addr);
139
}
140
141
if((addr & 0xe08000) == 0x208000) { //$20-3f:8000-ffff
142
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x007fff);
143
if(mmio.dbmode == 0) return read(0x100000 | addr);
144
return read((mmio.db << 20) | addr);
145
}
146
147
if((addr & 0xe08000) == 0x808000) { //$80-9f:8000-ffff
148
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x007fff);
149
if(mmio.ebmode == 0) return read(0x200000 | addr);
150
return read((mmio.eb << 20) | addr);
151
}
152
153
if((addr & 0xe08000) == 0xa08000) { //$a0-bf:8000-ffff
154
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x007fff);
155
if(mmio.fbmode == 0) return read(0x300000 | addr);
156
return read((mmio.fb << 20) | addr);
157
}
158
159
if((addr & 0xf00000) == 0xc00000) { //$c0-cf:0000-ffff
160
return read((mmio.cb << 20) | (addr & 0x0fffff));
161
}
162
163
if((addr & 0xf00000) == 0xd00000) { //$d0-df:0000-ffff
164
return read((mmio.db << 20) | (addr & 0x0fffff));
165
}
166
167
if((addr & 0xf00000) == 0xe00000) { //$e0-ef:0000-ffff
168
return read((mmio.eb << 20) | (addr & 0x0fffff));
169
}
170
171
if((addr & 0xf00000) == 0xf00000) { //$f0-ff:0000-ffff
172
return read((mmio.fb << 20) | (addr & 0x0fffff));
173
}
174
175
return 0x00;
176
}
177
178
void SA1::mmc_write(unsigned addr, uint8 data) {
179
}
180
181
uint8 SA1::mmc_cpu_read(unsigned addr) {
182
cpu.synchronize_coprocessors();
183
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
184
return cpubwram.read(addr);
185
}
186
187
void SA1::mmc_cpu_write(unsigned addr, uint8 data) {
188
cpu.synchronize_coprocessors();
189
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
190
cpubwram.write(addr, data);
191
}
192
193
uint8 SA1::mmc_sa1_read(unsigned addr) {
194
synchronize_cpu();
195
if(mmio.sw46 == 0) {
196
//$40-43:0000-ffff x 32 projection
197
addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), cartridge.ram.size());
198
return cartridge.ram.read(addr);
199
} else {
200
//$60-6f:0000-ffff x 128 projection
201
addr = bus.mirror(mmio.cbm * 0x2000 + (addr & 0x1fff), 0x100000);
202
return bitmap_read(addr);
203
}
204
}
205
206
void SA1::mmc_sa1_write(unsigned addr, uint8 data) {
207
synchronize_cpu();
208
if(mmio.sw46 == 0) {
209
//$40-43:0000-ffff x 32 projection
210
addr = bus.mirror((mmio.cbm & 0x1f) * 0x2000 + (addr & 0x1fff), cartridge.ram.size());
211
cartridge.ram.write(addr, data);
212
} else {
213
//$60-6f:0000-ffff x 128 projection
214
addr = bus.mirror(mmio.cbm * 0x2000 + (addr & 0x1fff), 0x100000);
215
bitmap_write(addr, data);
216
}
217
}
218
219
uint8 SA1::bitmap_read(unsigned addr) {
220
if(mmio.bbf == 0) {
221
//4bpp
222
unsigned shift = addr & 1;
223
addr = (addr >> 1) & (cartridge.ram.size() - 1);
224
switch(shift) { default:
225
case 0: return (cartridge.ram.read(addr) >> 0) & 15;
226
case 1: return (cartridge.ram.read(addr) >> 4) & 15;
227
}
228
} else {
229
//2bpp
230
unsigned shift = addr & 3;
231
addr = (addr >> 2) & (cartridge.ram.size() - 1);
232
switch(shift) { default:
233
case 0: return (cartridge.ram.read(addr) >> 0) & 3;
234
case 1: return (cartridge.ram.read(addr) >> 2) & 3;
235
case 2: return (cartridge.ram.read(addr) >> 4) & 3;
236
case 3: return (cartridge.ram.read(addr) >> 6) & 3;
237
}
238
}
239
}
240
241
void SA1::bitmap_write(unsigned addr, uint8 data) {
242
if(mmio.bbf == 0) {
243
//4bpp
244
unsigned shift = addr & 1;
245
addr = (addr >> 1) & (cartridge.ram.size() - 1);
246
switch(shift) { default:
247
case 0: data = (cartridge.ram.read(addr) & 0xf0) | ((data & 15) << 0); break;
248
case 1: data = (cartridge.ram.read(addr) & 0x0f) | ((data & 15) << 4); break;
249
}
250
} else {
251
//2bpp
252
unsigned shift = addr & 3;
253
addr = (addr >> 2) & (cartridge.ram.size() - 1);
254
switch(shift) { default:
255
case 0: data = (cartridge.ram.read(addr) & 0xfc) | ((data & 3) << 0); break;
256
case 1: data = (cartridge.ram.read(addr) & 0xf3) | ((data & 3) << 2); break;
257
case 2: data = (cartridge.ram.read(addr) & 0xcf) | ((data & 3) << 4); break;
258
case 3: data = (cartridge.ram.read(addr) & 0x3f) | ((data & 3) << 6); break;
259
}
260
}
261
262
cartridge.ram.write(addr, data);
263
}
264
265
#endif
266
267