Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/chip/sa1/sa1.cpp
2 views
1
#include <snes/snes.hpp>
2
3
#define SA1_CPP
4
namespace SNES {
5
6
SA1 sa1;
7
8
#include "serialization.cpp"
9
#include "bus/bus.cpp"
10
#include "dma/dma.cpp"
11
#include "memory/memory.cpp"
12
#include "mmio/mmio.cpp"
13
14
void SA1::Enter() { sa1.enter(); }
15
16
void SA1::enter() {
17
while(true) {
18
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
19
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
20
}
21
22
if(mmio.sa1_rdyb || mmio.sa1_resb) {
23
//SA-1 co-processor is asleep
24
tick();
25
synchronize_cpu();
26
continue;
27
}
28
29
if(status.interrupt_pending) {
30
status.interrupt_pending = false;
31
op_irq();
32
continue;
33
}
34
35
(this->*opcode_table[op_readpc()])();
36
}
37
}
38
39
void SA1::op_irq() {
40
op_read(regs.pc.d);
41
op_io();
42
if(!regs.e) op_writestack(regs.pc.b);
43
op_writestack(regs.pc.h);
44
op_writestack(regs.pc.l);
45
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
46
regs.pc.w = regs.vector;
47
regs.pc.b = 0x00;
48
regs.p.i = 1;
49
regs.p.d = 0;
50
}
51
52
void SA1::last_cycle() {
53
if(mmio.sa1_nmi && !mmio.sa1_nmicl) {
54
status.interrupt_pending = true;
55
regs.vector = mmio.cnv;
56
mmio.sa1_nmifl = true;
57
mmio.sa1_nmicl = 1;
58
regs.wai = false;
59
} else if(!regs.p.i) {
60
if(mmio.timer_irqen && !mmio.timer_irqcl) {
61
status.interrupt_pending = true;
62
regs.vector = mmio.civ;
63
mmio.timer_irqfl = true;
64
regs.wai = false;
65
} else if(mmio.dma_irqen && !mmio.dma_irqcl) {
66
status.interrupt_pending = true;
67
regs.vector = mmio.civ;
68
mmio.dma_irqfl = true;
69
regs.wai = false;
70
} else if(mmio.sa1_irq && !mmio.sa1_irqcl) {
71
status.interrupt_pending = true;
72
regs.vector = mmio.civ;
73
mmio.sa1_irqfl = true;
74
regs.wai = false;
75
}
76
}
77
}
78
79
bool SA1::interrupt_pending() {
80
return status.interrupt_pending;
81
}
82
83
void SA1::tick() {
84
step(2);
85
if(++status.tick_counter == 0) synchronize_cpu();
86
87
//adjust counters:
88
//note that internally, status counters are in clocks;
89
//whereas MMIO register counters are in dots (4 clocks = 1 dot)
90
if(mmio.hvselb == 0) {
91
//HV timer
92
status.hcounter += 2;
93
if(status.hcounter >= 1364) {
94
status.hcounter = 0;
95
if(++status.vcounter >= status.scanlines) status.vcounter = 0;
96
}
97
} else {
98
//linear timer
99
status.hcounter += 2;
100
status.vcounter += (status.hcounter >> 11);
101
status.hcounter &= 0x07ff;
102
status.vcounter &= 0x01ff;
103
}
104
105
//test counters for timer IRQ
106
switch((mmio.ven << 1) + (mmio.hen << 0)) {
107
case 0: break;
108
case 1: if(status.hcounter == (mmio.hcnt << 2)) trigger_irq(); break;
109
case 2: if(status.vcounter == mmio.vcnt && status.hcounter == 0) trigger_irq(); break;
110
case 3: if(status.vcounter == mmio.hcnt && status.hcounter == (mmio.hcnt << 2)) trigger_irq(); break;
111
}
112
}
113
114
void SA1::trigger_irq() {
115
mmio.timer_irqfl = true;
116
if(mmio.timer_irqen) mmio.timer_irqcl = 0;
117
}
118
119
void SA1::init() {
120
}
121
122
void SA1::load() {
123
}
124
125
void SA1::unload() {
126
}
127
128
void SA1::power() {
129
regs.a = regs.x = regs.y = 0x0000;
130
regs.s = 0x01ff;
131
}
132
133
void SA1::reset() {
134
create(SA1::Enter, system.cpu_frequency());
135
136
cpubwram.dma = false;
137
for(unsigned addr = 0; addr < iram.size(); addr++) {
138
iram.write(addr, 0x00);
139
}
140
141
regs.pc.d = 0x000000;
142
regs.x.h = 0x00;
143
regs.y.h = 0x00;
144
regs.s.h = 0x01;
145
regs.d = 0x0000;
146
regs.db = 0x00;
147
regs.p = 0x34;
148
regs.e = 1;
149
regs.mdr = 0x00;
150
regs.wai = false;
151
regs.vector = 0x0000;
152
CPUcore::update_table();
153
154
status.tick_counter = 0;
155
156
status.interrupt_pending = false;
157
158
status.scanlines = (system.region() == System::Region::NTSC ? 262 : 312);
159
status.vcounter = 0;
160
status.hcounter = 0;
161
162
dma.line = 0;
163
164
//$2200 CCNT
165
mmio.sa1_irq = false;
166
mmio.sa1_rdyb = false;
167
mmio.sa1_resb = true;
168
mmio.sa1_nmi = false;
169
mmio.smeg = 0;
170
171
//$2201 SIE
172
mmio.cpu_irqen = false;
173
mmio.chdma_irqen = false;
174
175
//$2202 SIC
176
mmio.cpu_irqcl = false;
177
mmio.chdma_irqcl = false;
178
179
//$2203,$2204 CRV
180
mmio.crv = 0x0000;
181
182
//$2205,$2206 CNV
183
mmio.cnv = 0x0000;
184
185
//$2207,$2208 CIV
186
mmio.civ = 0x0000;
187
188
//$2209 SCNT
189
mmio.cpu_irq = false;
190
mmio.cpu_ivsw = false;
191
mmio.cpu_nvsw = false;
192
mmio.cmeg = 0;
193
194
//$220a CIE
195
mmio.sa1_irqen = false;
196
mmio.timer_irqen = false;
197
mmio.dma_irqen = false;
198
mmio.sa1_nmien = false;
199
200
//$220b CIC
201
mmio.sa1_irqcl = false;
202
mmio.timer_irqcl = false;
203
mmio.dma_irqcl = false;
204
mmio.sa1_nmicl = false;
205
206
//$220c,$220d SNV
207
mmio.snv = 0x0000;
208
209
//$220e,$220f SIV
210
mmio.siv = 0x0000;
211
212
//$2210
213
mmio.hvselb = false;
214
mmio.ven = false;
215
mmio.hen = false;
216
217
//$2212,$2213 HCNT
218
mmio.hcnt = 0x0000;
219
220
//$2214,$2215 VCNT
221
mmio.vcnt = 0x0000;
222
223
//$2220-2223 CXB, DXB, EXB, FXB
224
mmio.cbmode = 1;
225
mmio.dbmode = 1;
226
mmio.ebmode = 1;
227
mmio.fbmode = 1;
228
229
mmio.cb = 0x00;
230
mmio.db = 0x01;
231
mmio.eb = 0x00;
232
mmio.fb = 0x01;
233
234
//$2224 BMAPS
235
mmio.sbm = 0x00;
236
237
//$2225 BMAP
238
mmio.sw46 = false;
239
mmio.cbm = 0x00;
240
241
//$2226 SWBE
242
mmio.swen = false;
243
244
//$2227 CWBE
245
mmio.cwen = false;
246
247
//$2228 BWPA
248
mmio.bwp = 0x0f;
249
250
//$2229 SIWP
251
mmio.siwp = 0x00;
252
253
//$222a CIWP
254
mmio.ciwp = 0x00;
255
256
//$2230 DCNT
257
mmio.dmaen = false;
258
mmio.dprio = false;
259
mmio.cden = false;
260
mmio.cdsel = false;
261
mmio.dd = 0;
262
mmio.sd = 0;
263
264
//$2231 CDMA
265
mmio.chdend = false;
266
mmio.dmasize = 0;
267
mmio.dmacb = 0;
268
269
//$2232-$2234 SDA
270
mmio.dsa = 0x000000;
271
272
//$2235-$2237 DDA
273
mmio.dda = 0x000000;
274
275
//$2238,$2239 DTC
276
mmio.dtc = 0x0000;
277
278
//$223f BBF
279
mmio.bbf = 0;
280
281
//$2240-$224f BRF
282
for(unsigned i = 0; i < 16; i++) {
283
mmio.brf[i] = 0x00;
284
}
285
286
//$2250 MCNT
287
mmio.acm = 0;
288
mmio.md = 0;
289
290
//$2251,$2252 MA
291
mmio.ma = 0x0000;
292
293
//$2253,$2254 MB
294
mmio.mb = 0x0000;
295
296
//$2258 VBD
297
mmio.hl = false;
298
mmio.vb = 16;
299
300
//$2259-$225b
301
mmio.va = 0x000000;
302
mmio.vbit = 0;
303
304
//$2300 SFR
305
mmio.cpu_irqfl = false;
306
mmio.chdma_irqfl = false;
307
308
//$2301 CFR
309
mmio.sa1_irqfl = false;
310
mmio.timer_irqfl = false;
311
mmio.dma_irqfl = false;
312
mmio.sa1_nmifl = false;
313
314
//$2302,$2303 HCR
315
mmio.hcr = 0x0000;
316
317
//$2304,$2305 VCR
318
mmio.vcr = 0x0000;
319
320
//$2306-$230a MR
321
mmio.mr = 0;
322
323
//$230b
324
mmio.overflow = false;
325
}
326
327
SA1::SA1() : iram(2048) {
328
}
329
330
}
331
332