1
by OV2
Initial 1.52 import |
1 |
/***********************************************************************************
|
2 |
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
3 |
||
4 |
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
|
5 |
Jerremy Koot (jkoot@snes9x.com)
|
|
6 |
||
7 |
(c) Copyright 2002 - 2004 Matthew Kendora
|
|
8 |
||
9 |
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
|
10 |
||
11 |
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
|
12 |
||
13 |
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
|
14 |
||
15 |
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
|
16 |
Kris Bleakley (codeviolation@hotmail.com)
|
|
17 |
||
18 |
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
|
19 |
Nach (n-a-c-h@users.sourceforge.net),
|
|
87
by OV2
Update copyright in all files |
20 |
|
21 |
(c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com)
|
|
1
by OV2
Initial 1.52 import |
22 |
|
23 |
(c) Copyright 2006 - 2007 nitsuja
|
|
24 |
||
290
by Brandon Wright
Update some copyrights, bump version number. |
25 |
(c) Copyright 2009 - 2016 BearOso,
|
1
by OV2
Initial 1.52 import |
26 |
OV2
|
27 |
||
28 |
||
29 |
BS-X C emulator code
|
|
30 |
(c) Copyright 2005 - 2006 Dreamer Nom,
|
|
31 |
zones
|
|
32 |
||
33 |
C4 x86 assembler and some C emulation code
|
|
34 |
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
|
35 |
Nach,
|
|
36 |
zsKnight (zsknight@zsnes.com)
|
|
37 |
||
38 |
C4 C++ code
|
|
39 |
(c) Copyright 2003 - 2006 Brad Jorsch,
|
|
40 |
Nach
|
|
41 |
||
42 |
DSP-1 emulator code
|
|
43 |
(c) Copyright 1998 - 2006 _Demo_,
|
|
44 |
Andreas Naive (andreasnaive@gmail.com),
|
|
45 |
Gary Henderson,
|
|
46 |
Ivar (ivar@snes9x.com),
|
|
47 |
John Weidman,
|
|
48 |
Kris Bleakley,
|
|
49 |
Matthew Kendora,
|
|
50 |
Nach,
|
|
51 |
neviksti (neviksti@hotmail.com)
|
|
52 |
||
53 |
DSP-2 emulator code
|
|
54 |
(c) Copyright 2003 John Weidman,
|
|
55 |
Kris Bleakley,
|
|
56 |
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
|
57 |
Matthew Kendora,
|
|
58 |
neviksti
|
|
59 |
||
60 |
DSP-3 emulator code
|
|
61 |
(c) Copyright 2003 - 2006 John Weidman,
|
|
62 |
Kris Bleakley,
|
|
63 |
Lancer,
|
|
64 |
z80 gaiden
|
|
65 |
||
66 |
DSP-4 emulator code
|
|
67 |
(c) Copyright 2004 - 2006 Dreamer Nom,
|
|
68 |
John Weidman,
|
|
69 |
Kris Bleakley,
|
|
70 |
Nach,
|
|
71 |
z80 gaiden
|
|
72 |
||
73 |
OBC1 emulator code
|
|
74 |
(c) Copyright 2001 - 2004 zsKnight,
|
|
75 |
pagefault (pagefault@zsnes.com),
|
|
76 |
Kris Bleakley
|
|
77 |
Ported from x86 assembler to C by sanmaiwashi
|
|
78 |
||
79 |
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
|
80 |
(c) Copyright 2002 Matthew Kendora with research by
|
|
81 |
zsKnight,
|
|
82 |
John Weidman,
|
|
83 |
Dark Force
|
|
84 |
||
85 |
SPC7110 and RTC C++ emulator code used in 1.52+
|
|
86 |
(c) Copyright 2009 byuu,
|
|
87 |
neviksti
|
|
88 |
||
89 |
S-DD1 C emulator code
|
|
90 |
(c) Copyright 2003 Brad Jorsch with research by
|
|
91 |
Andreas Naive,
|
|
92 |
John Weidman
|
|
93 |
||
94 |
S-RTC C emulator code
|
|
95 |
(c) Copyright 2001 - 2006 byuu,
|
|
96 |
John Weidman
|
|
97 |
||
98 |
ST010 C++ emulator code
|
|
99 |
(c) Copyright 2003 Feather,
|
|
100 |
John Weidman,
|
|
101 |
Kris Bleakley,
|
|
102 |
Matthew Kendora
|
|
103 |
||
104 |
Super FX x86 assembler emulator code
|
|
105 |
(c) Copyright 1998 - 2003 _Demo_,
|
|
106 |
pagefault,
|
|
107 |
zsKnight
|
|
108 |
||
109 |
Super FX C emulator code
|
|
110 |
(c) Copyright 1997 - 1999 Ivar,
|
|
111 |
Gary Henderson,
|
|
112 |
John Weidman
|
|
113 |
||
114 |
Sound emulator code used in 1.5-1.51
|
|
115 |
(c) Copyright 1998 - 2003 Brad Martin
|
|
116 |
(c) Copyright 1998 - 2006 Charles Bilyue'
|
|
117 |
||
118 |
Sound emulator code used in 1.52+
|
|
119 |
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
|
120 |
||
295
by Brandon Wright
Add byuu copyright for his S-SMP |
121 |
S-SMP emulator code used in 1.54+
|
122 |
(c) Copyright 2016 byuu
|
|
123 |
||
1
by OV2
Initial 1.52 import |
124 |
SH assembler code partly based on x86 assembler code
|
125 |
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
|
126 |
||
127 |
2xSaI filter
|
|
128 |
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
|
129 |
||
130 |
HQ2x, HQ3x, HQ4x filters
|
|
131 |
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
132 |
||
133 |
NTSC filter
|
|
134 |
(c) Copyright 2006 - 2007 Shay Green
|
|
135 |
||
136 |
GTK+ GUI code
|
|
290
by Brandon Wright
Update some copyrights, bump version number. |
137 |
(c) Copyright 2004 - 2016 BearOso
|
1
by OV2
Initial 1.52 import |
138 |
|
139 |
Win32 GUI code
|
|
140 |
(c) Copyright 2003 - 2006 blip,
|
|
141 |
funkyass,
|
|
142 |
Matthew Kendora,
|
|
143 |
Nach,
|
|
144 |
nitsuja
|
|
298
by Brandon Wright
Bump OV2 Windows port copyright. |
145 |
(c) Copyright 2009 - 2016 OV2
|
1
by OV2
Initial 1.52 import |
146 |
|
147 |
Mac OS GUI code
|
|
148 |
(c) Copyright 1998 - 2001 John Stiles
|
|
87
by OV2
Update copyright in all files |
149 |
(c) Copyright 2001 - 2011 zones
|
1
by OV2
Initial 1.52 import |
150 |
|
151 |
||
152 |
Specific ports contains the works of other authors. See headers in
|
|
153 |
individual files.
|
|
154 |
||
155 |
||
156 |
Snes9x homepage: http://www.snes9x.com/
|
|
157 |
||
158 |
Permission to use, copy, modify and/or distribute Snes9x in both binary
|
|
159 |
and source form, for non-commercial purposes, is hereby granted without
|
|
160 |
fee, providing that this license information and copyright notice appear
|
|
161 |
with all copies and any derived work.
|
|
162 |
||
163 |
This software is provided 'as-is', without any express or implied
|
|
164 |
warranty. In no event shall the authors be held liable for any damages
|
|
165 |
arising from the use of this software or it's derivatives.
|
|
166 |
||
167 |
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
168 |
seek permission of the copyright holders first. Commercial use includes,
|
|
169 |
but is not limited to, charging money for Snes9x or software derived from
|
|
170 |
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
|
171 |
using Snes9x as a promotion for your commercial product.
|
|
172 |
||
173 |
The copyright holders request that bug fixes and improvements to the code
|
|
174 |
should be forwarded to them so everyone can benefit from the modifications
|
|
175 |
in future versions.
|
|
176 |
||
177 |
Super NES and Super Nintendo Entertainment System are trademarks of
|
|
178 |
Nintendo Co., Limited and its subsidiary companies.
|
|
179 |
***********************************************************************************/
|
|
180 |
||
181 |
||
182 |
#include "snes9x.h" |
|
183 |
#include "memmap.h" |
|
184 |
||
185 |
#define CPU SA1
|
|
186 |
#define ICPU SA1
|
|
187 |
#define Registers SA1Registers
|
|
188 |
#define OpenBus SA1OpenBus
|
|
189 |
#define S9xGetByte S9xSA1GetByte
|
|
190 |
#define S9xGetWord S9xSA1GetWord
|
|
191 |
#define S9xSetByte S9xSA1SetByte
|
|
192 |
#define S9xSetWord S9xSA1SetWord
|
|
193 |
#define S9xSetPCBase S9xSA1SetPCBase
|
|
194 |
#define S9xOpcodesM1X1 S9xSA1OpcodesM1X1
|
|
195 |
#define S9xOpcodesM1X0 S9xSA1OpcodesM1X0
|
|
196 |
#define S9xOpcodesM0X1 S9xSA1OpcodesM0X1
|
|
197 |
#define S9xOpcodesM0X0 S9xSA1OpcodesM0X0
|
|
198 |
#define S9xOpcodesE1 S9xSA1OpcodesE1
|
|
199 |
#define S9xOpcodesSlow S9xSA1OpcodesSlow
|
|
200 |
#define S9xOpcode_IRQ S9xSA1Opcode_IRQ
|
|
201 |
#define S9xOpcode_NMI S9xSA1Opcode_NMI
|
|
202 |
#define S9xUnpackStatus S9xSA1UnpackStatus
|
|
203 |
#define S9xPackStatus S9xSA1PackStatus
|
|
204 |
#define S9xFixCycles S9xSA1FixCycles
|
|
205 |
#define Immediate8 SA1Immediate8
|
|
206 |
#define Immediate16 SA1Immediate16
|
|
207 |
#define Relative SA1Relative
|
|
208 |
#define RelativeLong SA1RelativeLong
|
|
209 |
#define Absolute SA1Absolute
|
|
210 |
#define AbsoluteLong SA1AbsoluteLong
|
|
211 |
#define AbsoluteIndirect SA1AbsoluteIndirect
|
|
212 |
#define AbsoluteIndirectLong SA1AbsoluteIndirectLong
|
|
213 |
#define AbsoluteIndexedIndirect SA1AbsoluteIndexedIndirect
|
|
214 |
#define Direct SA1Direct
|
|
215 |
#define DirectIndirectIndexed SA1DirectIndirectIndexed
|
|
216 |
#define DirectIndirectIndexedLong SA1DirectIndirectIndexedLong
|
|
217 |
#define DirectIndexedIndirect SA1DirectIndexedIndirect
|
|
218 |
#define DirectIndexedX SA1DirectIndexedX
|
|
219 |
#define DirectIndexedY SA1DirectIndexedY
|
|
220 |
#define AbsoluteIndexedX SA1AbsoluteIndexedX
|
|
221 |
#define AbsoluteIndexedY SA1AbsoluteIndexedY
|
|
222 |
#define AbsoluteLongIndexedX SA1AbsoluteLongIndexedX
|
|
223 |
#define DirectIndirect SA1DirectIndirect
|
|
224 |
#define DirectIndirectLong SA1DirectIndirectLong
|
|
225 |
#define StackRelative SA1StackRelative
|
|
226 |
#define StackRelativeIndirectIndexed SA1StackRelativeIndirectIndexed
|
|
227 |
||
228 |
#define SA1_OPCODES
|
|
229 |
||
230 |
#include "cpuops.cpp" |
|
231 |
||
26.1.1
by zones
Rewrite IRQ / Update SA-1 / Remove CPUShutdown |
232 |
static void S9xSA1UpdateTimer (void); |
233 |
||
1
by OV2
Initial 1.52 import |
234 |
|
235 |
void S9xSA1MainLoop (void) |
|
236 |
{
|
|
26.1.1
by zones
Rewrite IRQ / Update SA-1 / Remove CPUShutdown |
237 |
if (Memory.FillRAM[0x2200] & 0x60) |
238 |
{
|
|
239 |
SA1.Cycles += 6; // FIXME |
|
240 |
S9xSA1UpdateTimer(); |
|
241 |
return; |
|
242 |
}
|
|
243 |
||
244 |
// SA-1 NMI
|
|
245 |
if ((Memory.FillRAM[0x2200] & 0x10) && !(Memory.FillRAM[0x220b] & 0x10)) |
|
246 |
{
|
|
247 |
Memory.FillRAM[0x2301] |= 0x10; |
|
248 |
Memory.FillRAM[0x220b] |= 0x10; |
|
249 |
||
250 |
if (SA1.WaitingForInterrupt) |
|
251 |
{
|
|
252 |
SA1.WaitingForInterrupt = FALSE; |
|
253 |
SA1Registers.PCw++; |
|
254 |
}
|
|
255 |
||
256 |
S9xSA1Opcode_NMI(); |
|
257 |
}
|
|
258 |
else
|
|
259 |
if (!SA1CheckFlag(IRQ)) |
|
260 |
{
|
|
261 |
// SA-1 Timer IRQ
|
|
262 |
if ((Memory.FillRAM[0x220a] & 0x40) && !(Memory.FillRAM[0x220b] & 0x40)) |
|
263 |
{
|
|
264 |
Memory.FillRAM[0x2301] |= 0x40; |
|
265 |
||
266 |
if (SA1.WaitingForInterrupt) |
|
267 |
{
|
|
268 |
SA1.WaitingForInterrupt = FALSE; |
|
269 |
SA1Registers.PCw++; |
|
270 |
}
|
|
271 |
||
272 |
S9xSA1Opcode_IRQ(); |
|
273 |
}
|
|
274 |
else
|
|
275 |
// SA-1 DMA IRQ
|
|
276 |
if ((Memory.FillRAM[0x220a] & 0x20) && !(Memory.FillRAM[0x220b] & 0x20)) |
|
277 |
{
|
|
278 |
Memory.FillRAM[0x2301] |= 0x20; |
|
279 |
||
280 |
if (SA1.WaitingForInterrupt) |
|
281 |
{
|
|
282 |
SA1.WaitingForInterrupt = FALSE; |
|
283 |
SA1Registers.PCw++; |
|
284 |
}
|
|
285 |
||
286 |
S9xSA1Opcode_IRQ(); |
|
287 |
}
|
|
288 |
else
|
|
289 |
// SA-1 IRQ
|
|
290 |
if ((Memory.FillRAM[0x2200] & 0x80) && !(Memory.FillRAM[0x220b] & 0x80)) |
|
291 |
{
|
|
292 |
Memory.FillRAM[0x2301] |= 0x80; |
|
293 |
||
294 |
if (SA1.WaitingForInterrupt) |
|
295 |
{
|
|
296 |
SA1.WaitingForInterrupt = FALSE; |
|
297 |
SA1Registers.PCw++; |
|
298 |
}
|
|
299 |
||
300 |
S9xSA1Opcode_IRQ(); |
|
301 |
}
|
|
302 |
}
|
|
303 |
||
304 |
for (int i = 0; i < 3 && !(Memory.FillRAM[0x2200] & 0x60); i++) |
|
1
by OV2
Initial 1.52 import |
305 |
{
|
306 |
#ifdef DEBUGGER
|
|
307 |
if (SA1.Flags & TRACE_FLAG) |
|
308 |
S9xSA1Trace(); |
|
309 |
#endif
|
|
310 |
||
311 |
register uint8 Op; |
|
312 |
register struct SOpcodes *Opcodes; |
|
313 |
||
314 |
if (SA1.PCBase) |
|
315 |
{
|
|
316 |
SA1OpenBus = Op = SA1.PCBase[Registers.PCw]; |
|
317 |
Opcodes = SA1.S9xOpcodes; |
|
318 |
}
|
|
319 |
else
|
|
320 |
{
|
|
321 |
Op = S9xSA1GetByte(Registers.PBPC); |
|
322 |
Opcodes = S9xOpcodesSlow; |
|
323 |
}
|
|
324 |
||
325 |
if ((SA1Registers.PCw & MEMMAP_MASK) + SA1.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE) |
|
326 |
{
|
|
327 |
uint32 oldPC = SA1Registers.PBPC; |
|
328 |
S9xSA1SetPCBase(SA1Registers.PBPC); |
|
329 |
SA1Registers.PBPC = oldPC; |
|
330 |
Opcodes = S9xSA1OpcodesSlow; |
|
331 |
}
|
|
332 |
||
333 |
Registers.PCw++; |
|
334 |
(*Opcodes[Op].S9xOpcode)(); |
|
335 |
}
|
|
26.1.1
by zones
Rewrite IRQ / Update SA-1 / Remove CPUShutdown |
336 |
|
337 |
S9xSA1UpdateTimer(); |
|
338 |
}
|
|
339 |
||
340 |
static void S9xSA1UpdateTimer (void) // FIXME |
|
341 |
{
|
|
342 |
SA1.PrevHCounter = SA1.HCounter; |
|
343 |
||
344 |
if (Memory.FillRAM[0x2210] & 0x80) |
|
345 |
{
|
|
346 |
SA1.HCounter += (SA1.Cycles - SA1.PrevCycles); |
|
347 |
if (SA1.HCounter >= 0x800) |
|
348 |
{
|
|
349 |
SA1.HCounter -= 0x800; |
|
350 |
SA1.PrevHCounter -= 0x800; |
|
351 |
if (++SA1.VCounter >= 0x200) |
|
352 |
SA1.VCounter = 0; |
|
353 |
}
|
|
354 |
}
|
|
355 |
else
|
|
356 |
{
|
|
357 |
SA1.HCounter += (SA1.Cycles - SA1.PrevCycles); |
|
358 |
if (SA1.HCounter >= Timings.H_Max_Master) |
|
359 |
{
|
|
360 |
SA1.HCounter -= Timings.H_Max_Master; |
|
361 |
SA1.PrevHCounter -= Timings.H_Max_Master; |
|
362 |
if (++SA1.VCounter >= Timings.V_Max_Master) |
|
363 |
SA1.VCounter = 0; |
|
364 |
}
|
|
365 |
}
|
|
366 |
||
367 |
if (SA1.Cycles >= Timings.H_Max_Master) |
|
368 |
SA1.Cycles -= Timings.H_Max_Master; |
|
369 |
||
370 |
SA1.PrevCycles = SA1.Cycles; |
|
371 |
||
372 |
bool8 thisIRQ = Memory.FillRAM[0x2210] & 0x03; |
|
373 |
||
374 |
if (Memory.FillRAM[0x2210] & 0x01) |
|
375 |
{
|
|
376 |
if (SA1.PrevHCounter >= SA1.HTimerIRQPos * ONE_DOT_CYCLE || SA1.HCounter < SA1.HTimerIRQPos * ONE_DOT_CYCLE) |
|
377 |
thisIRQ = FALSE; |
|
378 |
}
|
|
379 |
||
380 |
if (Memory.FillRAM[0x2210] & 0x02) |
|
381 |
{
|
|
382 |
if (SA1.VCounter != SA1.VTimerIRQPos * ONE_DOT_CYCLE) |
|
383 |
thisIRQ = FALSE; |
|
384 |
}
|
|
385 |
||
386 |
// SA-1 Timer IRQ control
|
|
387 |
if (!SA1.TimerIRQLastState && thisIRQ) |
|
388 |
{
|
|
389 |
Memory.FillRAM[0x2301] |= 0x40; |
|
390 |
if (Memory.FillRAM[0x220a] & 0x40) |
|
391 |
{
|
|
392 |
Memory.FillRAM[0x220b] &= ~0x40; |
|
393 |
#ifdef DEBUGGER
|
|
394 |
S9xTraceFormattedMessage("--- SA-1 Timer IRQ triggered prev HC:%04d curr HC:%04d HTimer:%d Pos:%04d VTimer:%d Pos:%03d", |
|
395 |
SA1.PrevHCounter, SA1.HCounter, |
|
396 |
(Memory.FillRAM[0x2210] & 0x01) ? 1 : 0, SA1.HTimerIRQPos * ONE_DOT_CYCLE, |
|
397 |
(Memory.FillRAM[0x2210] & 0x02) ? 1 : 0, SA1.VTimerIRQPos); |
|
398 |
#endif
|
|
399 |
}
|
|
400 |
}
|
|
401 |
||
402 |
SA1.TimerIRQLastState = thisIRQ; |
|
1
by OV2
Initial 1.52 import |
403 |
}
|