Browse code

Update snes9x code from 1.53 to 1.6.0.

Notable differences from upstream:
* Did not use the same #include setup for the new byuu apu and instead chose to do things more traditionally, as the latter is also much easier to deal with in Visual Studio than just including .cpp files into other .cpp files...
* MSU1 support not included (I see no need for this in a plugin meant to be used for original SNES music).
* The dynamic rate control on the APU not included (I also see no need for it in this plugin).
* The extra resamplers I added in were removed as the original hermite resampler was folded into a single non-inhertiable resampler.
* Bits of cleanup.

Naram Qashat authored on 2021/04/19 21:20:36
Showing 1 changed files
... ...
@@ -1,179 +1,8 @@
1
-/***********************************************************************************
1
+/*****************************************************************************\
2 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),
20
-
21
-  (c) Copyright 2002 - 2011  zones (kasumitokoduck@yahoo.com)
22
-
23
-  (c) Copyright 2006 - 2007  nitsuja
24
-
25
-  (c) Copyright 2009 - 2011  BearOso,
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
-
121
-  SH assembler code partly based on x86 assembler code
122
-  (c) Copyright 2002 - 2004  Marcus Comstedt (marcus@mc.pp.se)
123
-
124
-  2xSaI filter
125
-  (c) Copyright 1999 - 2001  Derek Liauw Kie Fa
126
-
127
-  HQ2x, HQ3x, HQ4x filters
128
-  (c) Copyright 2003         Maxim Stepin (maxim@hiend3d.com)
129
-
130
-  NTSC filter
131
-  (c) Copyright 2006 - 2007  Shay Green
132
-
133
-  GTK+ GUI code
134
-  (c) Copyright 2004 - 2011  BearOso
135
-
136
-  Win32 GUI code
137
-  (c) Copyright 2003 - 2006  blip,
138
-                             funkyass,
139
-                             Matthew Kendora,
140
-                             Nach,
141
-                             nitsuja
142
-  (c) Copyright 2009 - 2011  OV2
143
-
144
-  Mac OS GUI code
145
-  (c) Copyright 1998 - 2001  John Stiles
146
-  (c) Copyright 2001 - 2011  zones
147
-
148
-
149
-  Specific ports contains the works of other authors. See headers in
150
-  individual files.
151
-
152
-
153
-  Snes9x homepage: http://www.snes9x.com/
154
-
155
-  Permission to use, copy, modify and/or distribute Snes9x in both binary
156
-  and source form, for non-commercial purposes, is hereby granted without
157
-  fee, providing that this license information and copyright notice appear
158
-  with all copies and any derived work.
159
-
160
-  This software is provided 'as-is', without any express or implied
161
-  warranty. In no event shall the authors be held liable for any damages
162
-  arising from the use of this software or it's derivatives.
163
-
164
-  Snes9x is freeware for PERSONAL USE only. Commercial users should
165
-  seek permission of the copyright holders first. Commercial use includes,
166
-  but is not limited to, charging money for Snes9x or software derived from
167
-  Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
168
-  using Snes9x as a promotion for your commercial product.
169
-
170
-  The copyright holders request that bug fixes and improvements to the code
171
-  should be forwarded to them so everyone can benefit from the modifications
172
-  in future versions.
173
-
174
-  Super NES and Super Nintendo Entertainment System are trademarks of
175
-  Nintendo Co., Limited and its subsidiary companies.
176
- ***********************************************************************************/
3
+                This file is licensed under the Snes9x License.
4
+   For further information, consult the LICENSE file in the root directory.
5
+\*****************************************************************************/
177 6
 
178 7
 #include "snes9x.h"
179 8
 #include "memmap.h"
... ...
@@ -216,46 +45,77 @@ static inline void S9xReschedule()
216 45
 	}
217 46
 }
218 47
 
48
+static void CHECK_FOR_IRQ_CHANGE()
49
+{
50
+	if (Timings.IRQFlagChanging)
51
+	{
52
+		if (Timings.IRQFlagChanging & IRQ_TRIGGER_NMI)
53
+		{
54
+			CPU.NMIPending = true;
55
+			Timings.NMITriggerPos = CPU.Cycles + 6;
56
+		}
57
+		if (Timings.IRQFlagChanging & IRQ_CLEAR_FLAG)
58
+			ClearIRQ();
59
+		else if (Timings.IRQFlagChanging & IRQ_SET_FLAG)
60
+			SetIRQ();
61
+		Timings.IRQFlagChanging = IRQ_NONE;
62
+	}
63
+}
64
+
219 65
 void S9xMainLoop()
220 66
 {
67
+	if (CPU.Flags & SCAN_KEYS_FLAG)
68
+		CPU.Flags &= ~SCAN_KEYS_FLAG;
69
+
221 70
 	for (;;)
222 71
 	{
223
-		if (CPU.NMILine)
72
+		if (CPU.NMIPending)
224 73
 		{
225 74
 			if (Timings.NMITriggerPos <= CPU.Cycles)
226 75
 			{
227
-				CPU.NMILine = false;
76
+				CPU.NMIPending = false;
228 77
 				Timings.NMITriggerPos = 0xffff;
229 78
 				if (CPU.WaitingForInterrupt)
230 79
 				{
231 80
 					CPU.WaitingForInterrupt = false;
232 81
 					++Registers.PC.W.xPC;
82
+					CPU.Cycles += TWO_CYCLES + ONE_DOT_CYCLE / 2;
83
+					while (CPU.Cycles >= CPU.NextEvent)
84
+						S9xDoHEventProcessing();
233 85
 				}
234 86
 
87
+				CHECK_FOR_IRQ_CHANGE();
235 88
 				S9xOpcode_NMI();
236 89
 			}
237 90
 		}
238 91
 
239
-		if (CPU.IRQTransition)
92
+		if (CPU.Cycles >= Timings.NextIRQTimer)
240 93
 		{
241
-			if (CPU.IRQPending)
242
-				--CPU.IRQPending;
243
-			else
244
-			{
245
-				if (CPU.WaitingForInterrupt)
246
-				{
247
-					CPU.WaitingForInterrupt = false;
248
-					++Registers.PC.W.xPC;
249
-				}
94
+			S9xUpdateIRQPositions(false);
95
+			CPU.IRQLine = true;
96
+		}
250 97
 
251
-				CPU.IRQTransition = false;
252
-				CPU.IRQPending = Timings.IRQPendCount;
98
+		if (CPU.IRQLine)
99
+		{
100
+			if (CPU.WaitingForInterrupt)
101
+			{
102
+				CPU.WaitingForInterrupt = false;
103
+				++Registers.PC.W.xPC;
104
+				CPU.Cycles += TWO_CYCLES + ONE_DOT_CYCLE / 2;
105
+				while (CPU.Cycles >= CPU.NextEvent)
106
+					S9xDoHEventProcessing();
107
+			}
253 108
 
254
-				if (!CheckFlag(IRQ))
255
-					S9xOpcode_IRQ();
109
+			if (!CheckFlag(IRQ))
110
+			{
111
+				/* The flag pushed onto the stack is the new value */
112
+				CHECK_FOR_IRQ_CHANGE();
113
+				S9xOpcode_IRQ();
256 114
 			}
257 115
 		}
258 116
 
117
+		CHECK_FOR_IRQ_CHANGE();
118
+
259 119
 		if (CPU.Flags & SCAN_KEYS_FLAG)
260 120
 			break;
261 121
 
... ...
@@ -265,9 +125,7 @@ void S9xMainLoop()
265 125
 		if (CPU.PCBase)
266 126
 		{
267 127
 			Op = CPU.PCBase[Registers.PC.W.xPC];
268
-			CPU.PrevCycles = CPU.Cycles;
269 128
 			CPU.Cycles += CPU.MemSpeed;
270
-			S9xCheckInterrupts();
271 129
 			Opcodes = ICPU.S9xOpcodes;
272 130
 		}
273 131
 		else
... ...
@@ -281,7 +139,7 @@ void S9xMainLoop()
281 139
 		{
282 140
 			uint8_t *oldPCBase = CPU.PCBase;
283 141
 
284
-			CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + (static_cast<uint16_t>(Registers.PC.W.xPC + 4)));
142
+			CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + static_cast<uint16_t>(Registers.PC.W.xPC + 4));
285 143
 			if (oldPCBase != CPU.PCBase || (Registers.PC.W.xPC & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
286 144
 				Opcodes = S9xOpcodesSlow;
287 145
 		}
... ...
@@ -291,9 +149,6 @@ void S9xMainLoop()
291 149
 	}
292 150
 
293 151
 	S9xPackStatus();
294
-
295
-	if (CPU.Flags & SCAN_KEYS_FLAG)
296
-		CPU.Flags &= ~SCAN_KEYS_FLAG;
297 152
 }
298 153
 
299 154
 void S9xDoHEventProcessing()
... ...
@@ -315,11 +170,11 @@ void S9xDoHEventProcessing()
315 170
 		case HC_HCOUNTER_MAX_EVENT:
316 171
 			S9xAPUEndScanline();
317 172
 			CPU.Cycles -= Timings.H_Max;
318
-			CPU.PrevCycles -= Timings.H_Max;
319
-			S9xAPUSetReferenceTime(CPU.Cycles);
320
-
321
-			if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
173
+			if (Timings.NMITriggerPos != 0xffff)
322 174
 				Timings.NMITriggerPos -= Timings.H_Max;
175
+			if (Timings.NextIRQTimer != 0x0fffffff)
176
+				Timings.NextIRQTimer -= Timings.H_Max;
177
+			S9xAPUSetReferenceTime(CPU.Cycles);
323 178
 
324 179
 			++CPU.V_Counter;
325 180
 			if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1
... ...
@@ -343,10 +198,6 @@ void S9xDoHEventProcessing()
343 198
 
344 199
 				// FIXME: reading $4210 will wait 2 cycles, then perform reading, then wait 4 more cycles.
345 200
 				Memory.FillRAM[0x4210] = Model->_5A22;
346
-				CPU.NMILine = false;
347
-				Timings.NMITriggerPos = 0xffff;
348
-
349
-				CPU.Flags |= SCAN_KEYS_FLAG;
350 201
 			}
351 202
 
352 203
 			// From byuu:
... ...
@@ -375,6 +226,8 @@ void S9xDoHEventProcessing()
375 226
 
376 227
 			if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) // VBlank starts from V=225(240).
377 228
 			{
229
+				CPU.Flags |= SCAN_KEYS_FLAG;
230
+
378 231
 				PPU.HDMA = 0;
379 232
 				// Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
380 233
 				PPU.ForcedBlanking = !!((Memory.FillRAM[0x2100] >> 7) & 1);
... ...
@@ -399,7 +252,7 @@ void S9xDoHEventProcessing()
399 252
 				{
400 253
 					// FIXME: triggered at HC=6, checked just before the final CPU cycle,
401 254
 					// then, when to call S9xOpcode_NMI()?
402
-					CPU.NMILine = true;
255
+					CPU.NMIPending = true;
403 256
 					Timings.NMITriggerPos = 6 + 6;
404 257
 				}
405 258
 			}
... ...
@@ -422,9 +275,7 @@ void S9xDoHEventProcessing()
422 275
 			break;
423 276
 
424 277
 		case HC_WRAM_REFRESH_EVENT:
425
-			CPU.PrevCycles = CPU.Cycles;
426 278
 			CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
427
-			S9xCheckInterrupts();
428 279
 
429 280
 			S9xReschedule();
430 281
 	}
Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -259,8 +259,8 @@ void S9xMainLoop()
259 259
 		if (CPU.Flags & SCAN_KEYS_FLAG)
260 260
 			break;
261 261
 
262
-		register uint8_t Op;
263
-		register SOpcodes *Opcodes;
262
+		uint8_t Op;
263
+		SOpcodes *Opcodes;
264 264
 
265 265
 		if (CPU.PCBase)
266 266
 		{
Browse code

[SNSF] Massive code cleanup, as well as removing as much unused code/variables as possible.

Naram Qashat authored on 2013/05/23 06:02:16
Showing 1 changed files
... ...
@@ -180,12 +180,6 @@
180 180
 #include "cpuops.h"
181 181
 #include "dma.h"
182 182
 #include "apu/apu.h"
183
-//#include "fxemu.h"
184
-//#include "snapshot.h"
185
-#ifdef DEBUGGER
186
-#include "debug.h"
187
-#include "missing.h"
188
-#endif
189 183
 
190 184
 static inline void S9xReschedule()
191 185
 {
... ...
@@ -193,33 +187,32 @@ static inline void S9xReschedule()
193 187
 	{
194 188
 		case HC_HBLANK_START_EVENT:
195 189
 			CPU.WhichEvent = HC_HDMA_START_EVENT;
196
-			CPU.NextEvent  = Timings.HDMAStart;
190
+			CPU.NextEvent = Timings.HDMAStart;
197 191
 			break;
198 192
 
199 193
 		case HC_HDMA_START_EVENT:
200 194
 			CPU.WhichEvent = HC_HCOUNTER_MAX_EVENT;
201
-			CPU.NextEvent  = Timings.H_Max;
195
+			CPU.NextEvent = Timings.H_Max;
202 196
 			break;
203 197
 
204 198
 		case HC_HCOUNTER_MAX_EVENT:
205 199
 			CPU.WhichEvent = HC_HDMA_INIT_EVENT;
206
-			CPU.NextEvent  = Timings.HDMAInit;
200
+			CPU.NextEvent = Timings.HDMAInit;
207 201
 			break;
208 202
 
209 203
 		case HC_HDMA_INIT_EVENT:
210 204
 			CPU.WhichEvent = HC_RENDER_EVENT;
211
-			CPU.NextEvent  = Timings.RenderPos;
205
+			CPU.NextEvent = Timings.RenderPos;
212 206
 			break;
213 207
 
214 208
 		case HC_RENDER_EVENT:
215 209
 			CPU.WhichEvent = HC_WRAM_REFRESH_EVENT;
216
-			CPU.NextEvent  = Timings.WRAMRefreshPos;
210
+			CPU.NextEvent = Timings.WRAMRefreshPos;
217 211
 			break;
218 212
 
219 213
 		case HC_WRAM_REFRESH_EVENT:
220 214
 			CPU.WhichEvent = HC_HBLANK_START_EVENT;
221
-			CPU.NextEvent  = Timings.HBlankStart;
222
-			break;
215
+			CPU.NextEvent = Timings.HBlankStart;
223 216
 	}
224 217
 }
225 218
 
... ...
@@ -236,23 +229,23 @@ void S9xMainLoop()
236 229
 				if (CPU.WaitingForInterrupt)
237 230
 				{
238 231
 					CPU.WaitingForInterrupt = false;
239
-					Registers.PCw++;
232
+					++Registers.PC.W.xPC;
240 233
 				}
241 234
 
242 235
 				S9xOpcode_NMI();
243 236
 			}
244 237
 		}
245 238
 
246
-		if (CPU.IRQTransition || CPU.IRQExternal)
239
+		if (CPU.IRQTransition)
247 240
 		{
248 241
 			if (CPU.IRQPending)
249
-				CPU.IRQPending--;
242
+				--CPU.IRQPending;
250 243
 			else
251 244
 			{
252 245
 				if (CPU.WaitingForInterrupt)
253 246
 				{
254 247
 					CPU.WaitingForInterrupt = false;
255
-					Registers.PCw++;
248
+					++Registers.PC.W.xPC;
256 249
 				}
257 250
 
258 251
 				CPU.IRQTransition = false;
... ...
@@ -263,45 +256,15 @@ void S9xMainLoop()
263 256
 			}
264 257
 		}
265 258
 
266
-	#ifdef DEBUGGER
267
-		if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
268
-		{
269
-			for (int Break = 0; Break != 6; Break++)
270
-			{
271
-				if (S9xBreakpoint[Break].Enabled &&
272
-					S9xBreakpoint[Break].Bank == Registers.PB &&
273
-					S9xBreakpoint[Break].Address == Registers.PCw)
274
-				{
275
-					if (S9xBreakpoint[Break].Enabled == 2)
276
-						S9xBreakpoint[Break].Enabled = true;
277
-					else
278
-						CPU.Flags |= DEBUG_MODE_FLAG;
279
-				}
280
-			}
281
-		}
282
-
283
-		if (CPU.Flags & DEBUG_MODE_FLAG)
284
-			break;
285
-
286
-		if (CPU.Flags & TRACE_FLAG)
287
-			S9xTrace();
288
-
289
-		if (CPU.Flags & SINGLE_STEP_FLAG)
290
-		{
291
-			CPU.Flags &= ~SINGLE_STEP_FLAG;
292
-			CPU.Flags |= DEBUG_MODE_FLAG;
293
-		}
294
-	#endif
295
-
296 259
 		if (CPU.Flags & SCAN_KEYS_FLAG)
297 260
 			break;
298 261
 
299
-		register uint8_t				Op;
300
-		register struct	SOpcodes	*Opcodes;
262
+		register uint8_t Op;
263
+		register SOpcodes *Opcodes;
301 264
 
302 265
 		if (CPU.PCBase)
303 266
 		{
304
-			Op = CPU.PCBase[Registers.PCw];
267
+			Op = CPU.PCBase[Registers.PC.W.xPC];
305 268
 			CPU.PrevCycles = CPU.Cycles;
306 269
 			CPU.Cycles += CPU.MemSpeed;
307 270
 			S9xCheckInterrupts();
... ...
@@ -309,60 +272,32 @@ void S9xMainLoop()
309 272
 		}
310 273
 		else
311 274
 		{
312
-			Op = S9xGetByte(Registers.PBPC);
275
+			Op = S9xGetByte(Registers.PC.xPBPC);
313 276
 			OpenBus = Op;
314 277
 			Opcodes = S9xOpcodesSlow;
315 278
 		}
316 279
 
317
-		if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
280
+		if ((Registers.PC.W.xPC & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
318 281
 		{
319
-			uint8_t	*oldPCBase = CPU.PCBase;
282
+			uint8_t *oldPCBase = CPU.PCBase;
320 283
 
321
-			CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16_t) (Registers.PCw + 4)));
322
-			if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
284
+			CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + (static_cast<uint16_t>(Registers.PC.W.xPC + 4)));
285
+			if (oldPCBase != CPU.PCBase || (Registers.PC.W.xPC & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
323 286
 				Opcodes = S9xOpcodesSlow;
324 287
 		}
325 288
 
326
-		Registers.PCw++;
289
+		++Registers.PC.W.xPC;
327 290
 		(*Opcodes[Op].S9xOpcode)();
328
-
329
-		/*if (Settings.SA1)
330
-			S9xSA1MainLoop();*/
331 291
 	}
332 292
 
333 293
 	S9xPackStatus();
334 294
 
335 295
 	if (CPU.Flags & SCAN_KEYS_FLAG)
336
-	{
337
-	/*#ifdef DEBUGGER
338
-		if (!(CPU.Flags & FRAME_ADVANCE_FLAG))
339
-	#endif
340
-		S9xSyncSpeed();*/
341 296
 		CPU.Flags &= ~SCAN_KEYS_FLAG;
342
-	}
343 297
 }
344 298
 
345 299
 void S9xDoHEventProcessing()
346 300
 {
347
-#ifdef DEBUGGER
348
-	static char	eventname[7][32] =
349
-	{
350
-		"",
351
-		"HC_HBLANK_START_EVENT",
352
-		"HC_HDMA_START_EVENT  ",
353
-		"HC_HCOUNTER_MAX_EVENT",
354
-		"HC_HDMA_INIT_EVENT   ",
355
-		"HC_RENDER_EVENT      ",
356
-		"HC_WRAM_REFRESH_EVENT"
357
-	};
358
-#endif
359
-
360
-#ifdef DEBUGGER
361
-	if (Settings.TraceHCEvent)
362
-		S9xTraceFormattedMessage("--- HC event processing  (%s)  expected HC:%04d  executed HC:%04d",
363
-			eventname[CPU.WhichEvent], CPU.NextEvent, CPU.Cycles);
364
-#endif
365
-
366 301
 	switch (CPU.WhichEvent)
367 302
 	{
368 303
 		case HC_HBLANK_START_EVENT:
... ...
@@ -373,23 +308,11 @@ void S9xDoHEventProcessing()
373 308
 			S9xReschedule();
374 309
 
375 310
 			if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
376
-			{
377
-			#ifdef DEBUGGER
378
-				S9xTraceFormattedMessage("*** HDMA Transfer HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
379
-			#endif
380 311
 				PPU.HDMA = S9xDoHDMA(PPU.HDMA);
381
-			}
382 312
 
383 313
 			break;
384 314
 
385 315
 		case HC_HCOUNTER_MAX_EVENT:
386
-			/*if (Settings.SuperFX)
387
-			{
388
-				if (!SuperFX.oneLineDone)
389
-					S9xSuperFXExec();
390
-				SuperFX.oneLineDone = false;
391
-			}*/
392
-
393 316
 			S9xAPUEndScanline();
394 317
 			CPU.Cycles -= Timings.H_Max;
395 318
 			CPU.PrevCycles -= Timings.H_Max;
... ...
@@ -398,11 +321,11 @@ void S9xDoHEventProcessing()
398 321
 			if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
399 322
 				Timings.NMITriggerPos -= Timings.H_Max;
400 323
 
401
-			CPU.V_Counter++;
402
-			if (CPU.V_Counter >= Timings.V_Max)	// V ranges from 0 to Timings.V_Max - 1
324
+			++CPU.V_Counter;
325
+			if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1
403 326
 			{
404 327
 				CPU.V_Counter = 0;
405
-				Timings.InterlaceField ^= 1;
328
+				Timings.InterlaceField = !Timings.InterlaceField;
406 329
 
407 330
 				// From byuu:
408 331
 				// [NTSC]
... ...
@@ -412,20 +335,17 @@ void S9xDoHEventProcessing()
412 335
 				// interlace mode has 625 scanlines: 313 on the even frame, and 312 on the odd.
413 336
 				// non-interlace mode has 624 scanlines: 312 scanlines on both even and odd frames.
414 337
 				if (IPPU.Interlace && !Timings.InterlaceField)
415
-					Timings.V_Max = Timings.V_Max_Master + 1;	// 263 (NTSC), 313?(PAL)
338
+					Timings.V_Max = Timings.V_Max_Master + 1; // 263 (NTSC), 313?(PAL)
416 339
 				else
417
-					Timings.V_Max = Timings.V_Max_Master;		// 262 (NTSC), 312?(PAL)
340
+					Timings.V_Max = Timings.V_Max_Master; // 262 (NTSC), 312?(PAL)
418 341
 
419 342
 				Memory.FillRAM[0x213F] ^= 0x80;
420
-				PPU.RangeTimeOver = 0;
421 343
 
422 344
 				// FIXME: reading $4210 will wait 2 cycles, then perform reading, then wait 4 more cycles.
423 345
 				Memory.FillRAM[0x4210] = Model->_5A22;
424 346
 				CPU.NMILine = false;
425 347
 				Timings.NMITriggerPos = 0xffff;
426 348
 
427
-				ICPU.Frame++;
428
-				PPU.HVBeamCounterLatched = 0;
429 349
 				CPU.Flags |= SCAN_KEYS_FLAG;
430 350
 			}
431 351
 
... ...
@@ -435,48 +355,40 @@ void S9xDoHEventProcessing()
435 355
 			// In interlace mode, there are always 341 dots per scanline. Even frames have 263 scanlines,
436 356
 			// and odd frames have 262 scanlines.
437 357
 			// Interlace mode scanline 240 on odd frames is not missing a dot.
438
-			if (CPU.V_Counter == 240 && !IPPU.Interlace && Timings.InterlaceField)	// V=240
439
-				Timings.H_Max = Timings.H_Max_Master - ONE_DOT_CYCLE;	// HC=1360
358
+			if (CPU.V_Counter == 240 && !IPPU.Interlace && Timings.InterlaceField) // V=240
359
+				Timings.H_Max = Timings.H_Max_Master - ONE_DOT_CYCLE; // HC=1360
440 360
 			else
441
-				Timings.H_Max = Timings.H_Max_Master;					// HC=1364
361
+				Timings.H_Max = Timings.H_Max_Master; // HC=1364
442 362
 
443 363
 			if (Model->_5A22 == 2)
444 364
 			{
445 365
 				if (CPU.V_Counter != 240 || IPPU.Interlace || !Timings.InterlaceField)	// V=240
446 366
 				{
447
-					if (Timings.WRAMRefreshPos == SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE)	// HC=534
448
-						Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2;					// HC=538
367
+					if (Timings.WRAMRefreshPos == SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE) // HC=534
368
+						Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2; // HC=538
449 369
 					else
450
-						Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE;	// HC=534
370
+						Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE; // HC=534
451 371
 				}
452 372
 			}
453 373
 			else
454 374
 				Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
455 375
 
456
-			if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)	// VBlank starts from V=225(240).
376
+			if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) // VBlank starts from V=225(240).
457 377
 			{
458
-				//S9xEndScreenRefresh();
459 378
 				PPU.HDMA = 0;
460 379
 				// Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
461
-			#ifdef DEBUGGER
462
-				missing.dma_this_frame = 0;
463
-			#endif
464
-				IPPU.MaxBrightness = PPU.Brightness;
465
-				PPU.ForcedBlanking = (Memory.FillRAM[0x2100] >> 7) & 1;
380
+				PPU.ForcedBlanking = !!((Memory.FillRAM[0x2100] >> 7) & 1);
466 381
 
467 382
 				if (!PPU.ForcedBlanking)
468 383
 				{
469 384
 					PPU.OAMAddr = PPU.SavedOAMAddr;
470 385
 
471
-					uint8_t	tmp = 0;
386
+					uint8_t tmp = 0;
472 387
 
473 388
 					if (PPU.OAMPriorityRotation)
474 389
 						tmp = (PPU.OAMAddr & 0xFE) >> 1;
475 390
 					if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
476
-					{
477 391
 						PPU.FirstSprite = tmp;
478
-						IPPU.OBJChanged = true;
479
-					}
480 392
 
481 393
 					PPU.OAMFlip = 0;
482 394
 				}
... ...
@@ -490,18 +402,8 @@ void S9xDoHEventProcessing()
490 402
 					CPU.NMILine = true;
491 403
 					Timings.NMITriggerPos = 6 + 6;
492 404
 				}
493
-
494 405
 			}
495 406
 
496
-			/*if (CPU.V_Counter == PPU.ScreenHeight + 3)	// FIXME: not true
497
-			{
498
-				if (Memory.FillRAM[0x4200] & 1)
499
-					S9xDoAutoJoypad();
500
-			}*/
501
-
502
-			/*if (CPU.V_Counter == FIRST_VISIBLE_LINE)	// V=1
503
-				S9xStartScreenRefresh();*/
504
-
505 407
 			S9xReschedule();
506 408
 
507 409
 			break;
... ...
@@ -509,41 +411,21 @@ void S9xDoHEventProcessing()
509 411
 		case HC_HDMA_INIT_EVENT:
510 412
 			S9xReschedule();
511 413
 
512
-			if (CPU.V_Counter == 0)
513
-			{
514
-			#ifdef DEBUGGER
515
-				S9xTraceFormattedMessage("*** HDMA Init     HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
516
-			#endif
414
+			if (!CPU.V_Counter)
517 415
 				S9xStartHDMA();
518
-			}
519 416
 
520 417
 			break;
521 418
 
522 419
 		case HC_RENDER_EVENT:
523
-			/*if (CPU.V_Counter >= FIRST_VISIBLE_LINE && CPU.V_Counter <= PPU.ScreenHeight)
524
-				RenderLine((uint8_t) (CPU.V_Counter - FIRST_VISIBLE_LINE));*/
525
-
526 420
 			S9xReschedule();
527 421
 
528 422
 			break;
529 423
 
530 424
 		case HC_WRAM_REFRESH_EVENT:
531
-		#ifdef DEBUGGER
532
-			S9xTraceFormattedMessage("*** WRAM Refresh  HC:%04d", CPU.Cycles);
533
-		#endif
534
-
535 425
 			CPU.PrevCycles = CPU.Cycles;
536 426
 			CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
537 427
 			S9xCheckInterrupts();
538 428
 
539 429
 			S9xReschedule();
540
-
541
-			break;
542 430
 	}
543
-
544
-#ifdef DEBUGGER
545
-	if (Settings.TraceHCEvent)
546
-		S9xTraceFormattedMessage("--- HC event rescheduled (%s)  expected HC:%04d  current  HC:%04d",
547
-			eventname[CPU.WhichEvent], CPU.NextEvent, CPU.Cycles);
548
-#endif
549 431
 }
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,549 @@
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),
20
+
21
+  (c) Copyright 2002 - 2011  zones (kasumitokoduck@yahoo.com)
22
+
23
+  (c) Copyright 2006 - 2007  nitsuja
24
+
25
+  (c) Copyright 2009 - 2011  BearOso,
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
+
121
+  SH assembler code partly based on x86 assembler code
122
+  (c) Copyright 2002 - 2004  Marcus Comstedt (marcus@mc.pp.se)
123
+
124
+  2xSaI filter
125
+  (c) Copyright 1999 - 2001  Derek Liauw Kie Fa
126
+
127
+  HQ2x, HQ3x, HQ4x filters
128
+  (c) Copyright 2003         Maxim Stepin (maxim@hiend3d.com)
129
+
130
+  NTSC filter
131
+  (c) Copyright 2006 - 2007  Shay Green
132
+
133
+  GTK+ GUI code
134
+  (c) Copyright 2004 - 2011  BearOso
135
+
136
+  Win32 GUI code
137
+  (c) Copyright 2003 - 2006  blip,
138
+                             funkyass,
139
+                             Matthew Kendora,
140
+                             Nach,
141
+                             nitsuja
142
+  (c) Copyright 2009 - 2011  OV2
143
+
144
+  Mac OS GUI code
145
+  (c) Copyright 1998 - 2001  John Stiles
146
+  (c) Copyright 2001 - 2011  zones
147
+
148
+
149
+  Specific ports contains the works of other authors. See headers in
150
+  individual files.
151
+
152
+
153
+  Snes9x homepage: http://www.snes9x.com/
154
+
155
+  Permission to use, copy, modify and/or distribute Snes9x in both binary
156
+  and source form, for non-commercial purposes, is hereby granted without
157
+  fee, providing that this license information and copyright notice appear
158
+  with all copies and any derived work.
159
+
160
+  This software is provided 'as-is', without any express or implied
161
+  warranty. In no event shall the authors be held liable for any damages
162
+  arising from the use of this software or it's derivatives.
163
+
164
+  Snes9x is freeware for PERSONAL USE only. Commercial users should
165
+  seek permission of the copyright holders first. Commercial use includes,
166
+  but is not limited to, charging money for Snes9x or software derived from
167
+  Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
168
+  using Snes9x as a promotion for your commercial product.
169
+
170
+  The copyright holders request that bug fixes and improvements to the code
171
+  should be forwarded to them so everyone can benefit from the modifications
172
+  in future versions.
173
+
174
+  Super NES and Super Nintendo Entertainment System are trademarks of
175
+  Nintendo Co., Limited and its subsidiary companies.
176
+ ***********************************************************************************/
177
+
178
+#include "snes9x.h"
179
+#include "memmap.h"
180
+#include "cpuops.h"
181
+#include "dma.h"
182
+#include "apu/apu.h"
183
+//#include "fxemu.h"
184
+//#include "snapshot.h"
185
+#ifdef DEBUGGER
186
+#include "debug.h"
187
+#include "missing.h"
188
+#endif
189
+
190
+static inline void S9xReschedule()
191
+{
192
+	switch (CPU.WhichEvent)
193
+	{
194
+		case HC_HBLANK_START_EVENT:
195
+			CPU.WhichEvent = HC_HDMA_START_EVENT;
196
+			CPU.NextEvent  = Timings.HDMAStart;
197
+			break;
198
+
199
+		case HC_HDMA_START_EVENT:
200
+			CPU.WhichEvent = HC_HCOUNTER_MAX_EVENT;
201
+			CPU.NextEvent  = Timings.H_Max;
202
+			break;
203
+
204
+		case HC_HCOUNTER_MAX_EVENT:
205
+			CPU.WhichEvent = HC_HDMA_INIT_EVENT;
206
+			CPU.NextEvent  = Timings.HDMAInit;
207
+			break;
208
+
209
+		case HC_HDMA_INIT_EVENT:
210
+			CPU.WhichEvent = HC_RENDER_EVENT;
211
+			CPU.NextEvent  = Timings.RenderPos;
212
+			break;
213
+
214
+		case HC_RENDER_EVENT:
215
+			CPU.WhichEvent = HC_WRAM_REFRESH_EVENT;
216
+			CPU.NextEvent  = Timings.WRAMRefreshPos;
217
+			break;
218
+
219
+		case HC_WRAM_REFRESH_EVENT:
220
+			CPU.WhichEvent = HC_HBLANK_START_EVENT;
221
+			CPU.NextEvent  = Timings.HBlankStart;
222
+			break;
223
+	}
224
+}
225
+
226
+void S9xMainLoop()
227
+{
228
+	for (;;)
229
+	{
230
+		if (CPU.NMILine)
231
+		{
232
+			if (Timings.NMITriggerPos <= CPU.Cycles)
233
+			{
234
+				CPU.NMILine = false;
235
+				Timings.NMITriggerPos = 0xffff;
236
+				if (CPU.WaitingForInterrupt)
237
+				{
238
+					CPU.WaitingForInterrupt = false;
239
+					Registers.PCw++;
240
+				}
241
+
242
+				S9xOpcode_NMI();
243
+			}
244
+		}
245
+
246
+		if (CPU.IRQTransition || CPU.IRQExternal)
247
+		{
248
+			if (CPU.IRQPending)
249
+				CPU.IRQPending--;
250
+			else
251
+			{
252
+				if (CPU.WaitingForInterrupt)
253
+				{
254
+					CPU.WaitingForInterrupt = false;
255
+					Registers.PCw++;
256
+				}
257
+
258
+				CPU.IRQTransition = false;
259
+				CPU.IRQPending = Timings.IRQPendCount;
260
+
261
+				if (!CheckFlag(IRQ))
262
+					S9xOpcode_IRQ();
263
+			}
264
+		}
265
+
266
+	#ifdef DEBUGGER
267
+		if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
268
+		{
269
+			for (int Break = 0; Break != 6; Break++)
270
+			{
271
+				if (S9xBreakpoint[Break].Enabled &&
272
+					S9xBreakpoint[Break].Bank == Registers.PB &&
273
+					S9xBreakpoint[Break].Address == Registers.PCw)
274
+				{
275
+					if (S9xBreakpoint[Break].Enabled == 2)
276
+						S9xBreakpoint[Break].Enabled = true;
277
+					else
278
+						CPU.Flags |= DEBUG_MODE_FLAG;
279
+				}
280
+			}
281
+		}
282
+
283
+		if (CPU.Flags & DEBUG_MODE_FLAG)
284
+			break;
285
+
286
+		if (CPU.Flags & TRACE_FLAG)
287
+			S9xTrace();
288
+
289
+		if (CPU.Flags & SINGLE_STEP_FLAG)
290
+		{
291
+			CPU.Flags &= ~SINGLE_STEP_FLAG;
292
+			CPU.Flags |= DEBUG_MODE_FLAG;
293
+		}
294
+	#endif
295
+
296
+		if (CPU.Flags & SCAN_KEYS_FLAG)
297
+			break;
298
+
299
+		register uint8_t				Op;
300
+		register struct	SOpcodes	*Opcodes;
301
+
302
+		if (CPU.PCBase)
303
+		{
304
+			Op = CPU.PCBase[Registers.PCw];
305
+			CPU.PrevCycles = CPU.Cycles;
306
+			CPU.Cycles += CPU.MemSpeed;
307
+			S9xCheckInterrupts();
308
+			Opcodes = ICPU.S9xOpcodes;
309
+		}
310
+		else
311
+		{
312
+			Op = S9xGetByte(Registers.PBPC);
313
+			OpenBus = Op;
314
+			Opcodes = S9xOpcodesSlow;
315
+		}
316
+
317
+		if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
318
+		{
319
+			uint8_t	*oldPCBase = CPU.PCBase;
320
+
321
+			CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16_t) (Registers.PCw + 4)));
322
+			if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
323
+				Opcodes = S9xOpcodesSlow;
324
+		}
325
+
326
+		Registers.PCw++;
327
+		(*Opcodes[Op].S9xOpcode)();
328
+
329
+		/*if (Settings.SA1)
330
+			S9xSA1MainLoop();*/
331
+	}
332
+
333
+	S9xPackStatus();
334
+
335
+	if (CPU.Flags & SCAN_KEYS_FLAG)
336
+	{
337
+	/*#ifdef DEBUGGER
338
+		if (!(CPU.Flags & FRAME_ADVANCE_FLAG))
339
+	#endif
340
+		S9xSyncSpeed();*/
341
+		CPU.Flags &= ~SCAN_KEYS_FLAG;
342
+	}
343
+}
344
+
345
+void S9xDoHEventProcessing()
346
+{
347
+#ifdef DEBUGGER
348
+	static char	eventname[7][32] =
349
+	{
350
+		"",
351
+		"HC_HBLANK_START_EVENT",
352
+		"HC_HDMA_START_EVENT  ",
353
+		"HC_HCOUNTER_MAX_EVENT",
354
+		"HC_HDMA_INIT_EVENT   ",
355
+		"HC_RENDER_EVENT      ",
356
+		"HC_WRAM_REFRESH_EVENT"
357
+	};
358
+#endif
359
+
360
+#ifdef DEBUGGER
361
+	if (Settings.TraceHCEvent)
362
+		S9xTraceFormattedMessage("--- HC event processing  (%s)  expected HC:%04d  executed HC:%04d",
363
+			eventname[CPU.WhichEvent], CPU.NextEvent, CPU.Cycles);
364
+#endif
365
+
366
+	switch (CPU.WhichEvent)
367
+	{
368
+		case HC_HBLANK_START_EVENT:
369
+			S9xReschedule();
370
+			break;
371
+
372
+		case HC_HDMA_START_EVENT:
373
+			S9xReschedule();
374
+
375
+			if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
376
+			{
377
+			#ifdef DEBUGGER
378
+				S9xTraceFormattedMessage("*** HDMA Transfer HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
379
+			#endif
380
+				PPU.HDMA = S9xDoHDMA(PPU.HDMA);
381
+			}
382
+
383
+			break;
384
+
385
+		case HC_HCOUNTER_MAX_EVENT:
386
+			/*if (Settings.SuperFX)
387
+			{
388
+				if (!SuperFX.oneLineDone)
389
+					S9xSuperFXExec();
390
+				SuperFX.oneLineDone = false;
391
+			}*/
392
+
393
+			S9xAPUEndScanline();
394
+			CPU.Cycles -= Timings.H_Max;
395
+			CPU.PrevCycles -= Timings.H_Max;
396
+			S9xAPUSetReferenceTime(CPU.Cycles);
397
+
398
+			if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
399
+				Timings.NMITriggerPos -= Timings.H_Max;
400
+
401
+			CPU.V_Counter++;
402
+			if (CPU.V_Counter >= Timings.V_Max)	// V ranges from 0 to Timings.V_Max - 1
403
+			{
404
+				CPU.V_Counter = 0;
405
+				Timings.InterlaceField ^= 1;
406
+
407
+				// From byuu:
408
+				// [NTSC]
409
+				// interlace mode has 525 scanlines: 263 on the even frame, and 262 on the odd.
410
+				// non-interlace mode has 524 scanlines: 262 scanlines on both even and odd frames.
411
+				// [PAL] <PAL info is unverified on hardware>
412
+				// interlace mode has 625 scanlines: 313 on the even frame, and 312 on the odd.
413
+				// non-interlace mode has 624 scanlines: 312 scanlines on both even and odd frames.
414
+				if (IPPU.Interlace && !Timings.InterlaceField)
415
+					Timings.V_Max = Timings.V_Max_Master + 1;	// 263 (NTSC), 313?(PAL)
416
+				else
417
+					Timings.V_Max = Timings.V_Max_Master;		// 262 (NTSC), 312?(PAL)
418
+
419
+				Memory.FillRAM[0x213F] ^= 0x80;
420
+				PPU.RangeTimeOver = 0;
421
+
422
+				// FIXME: reading $4210 will wait 2 cycles, then perform reading, then wait 4 more cycles.
423
+				Memory.FillRAM[0x4210] = Model->_5A22;
424
+				CPU.NMILine = false;
425
+				Timings.NMITriggerPos = 0xffff;
426
+
427
+				ICPU.Frame++;
428
+				PPU.HVBeamCounterLatched = 0;
429
+				CPU.Flags |= SCAN_KEYS_FLAG;
430
+			}
431
+
432
+			// From byuu:
433
+			// In non-interlace mode, there are 341 dots per scanline, and 262 scanlines per frame.
434
+			// On odd frames, scanline 240 is one dot short.
435
+			// In interlace mode, there are always 341 dots per scanline. Even frames have 263 scanlines,
436
+			// and odd frames have 262 scanlines.
437
+			// Interlace mode scanline 240 on odd frames is not missing a dot.
438
+			if (CPU.V_Counter == 240 && !IPPU.Interlace && Timings.InterlaceField)	// V=240
439
+				Timings.H_Max = Timings.H_Max_Master - ONE_DOT_CYCLE;	// HC=1360
440
+			else
441
+				Timings.H_Max = Timings.H_Max_Master;					// HC=1364
442
+
443
+			if (Model->_5A22 == 2)
444
+			{
445
+				if (CPU.V_Counter != 240 || IPPU.Interlace || !Timings.InterlaceField)	// V=240
446
+				{
447
+					if (Timings.WRAMRefreshPos == SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE)	// HC=534
448
+						Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2;					// HC=538
449
+					else
450
+						Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE;	// HC=534
451
+				}
452
+			}
453
+			else
454
+				Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
455
+
456
+			if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)	// VBlank starts from V=225(240).
457
+			{
458
+				//S9xEndScreenRefresh();
459
+				PPU.HDMA = 0;
460
+				// Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
461
+			#ifdef DEBUGGER
462
+				missing.dma_this_frame = 0;
463
+			#endif
464
+				IPPU.MaxBrightness = PPU.Brightness;
465
+				PPU.ForcedBlanking = (Memory.FillRAM[0x2100] >> 7) & 1;
466
+
467
+				if (!PPU.ForcedBlanking)
468
+				{
469
+					PPU.OAMAddr = PPU.SavedOAMAddr;
470
+
471
+					uint8_t	tmp = 0;
472
+
473
+					if (PPU.OAMPriorityRotation)
474
+						tmp = (PPU.OAMAddr & 0xFE) >> 1;
475
+					if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
476
+					{
477
+						PPU.FirstSprite = tmp;
478
+						IPPU.OBJChanged = true;
479
+					}
480
+
481
+					PPU.OAMFlip = 0;
482
+				}
483
+
484
+				// FIXME: writing to $4210 will wait 6 cycles.
485
+				Memory.FillRAM[0x4210] = 0x80 | Model->_5A22;
486
+				if (Memory.FillRAM[0x4200] & 0x80)
487
+				{
488
+					// FIXME: triggered at HC=6, checked just before the final CPU cycle,
489
+					// then, when to call S9xOpcode_NMI()?
490
+					CPU.NMILine = true;
491
+					Timings.NMITriggerPos = 6 + 6;
492
+				}
493
+
494
+			}
495
+
496
+			/*if (CPU.V_Counter == PPU.ScreenHeight + 3)	// FIXME: not true
497
+			{
498
+				if (Memory.FillRAM[0x4200] & 1)
499
+					S9xDoAutoJoypad();
500
+			}*/
501
+
502
+			/*if (CPU.V_Counter == FIRST_VISIBLE_LINE)	// V=1
503
+				S9xStartScreenRefresh();*/
504
+
505
+			S9xReschedule();
506
+
507
+			break;
508
+
509
+		case HC_HDMA_INIT_EVENT:
510
+			S9xReschedule();
511
+
512
+			if (CPU.V_Counter == 0)
513
+			{
514
+			#ifdef DEBUGGER
515
+				S9xTraceFormattedMessage("*** HDMA Init     HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
516
+			#endif
517
+				S9xStartHDMA();
518
+			}
519
+
520
+			break;
521
+
522
+		case HC_RENDER_EVENT:
523
+			/*if (CPU.V_Counter >= FIRST_VISIBLE_LINE && CPU.V_Counter <= PPU.ScreenHeight)
524
+				RenderLine((uint8_t) (CPU.V_Counter - FIRST_VISIBLE_LINE));*/
525
+
526
+			S9xReschedule();
527
+
528
+			break;
529
+
530
+		case HC_WRAM_REFRESH_EVENT:
531
+		#ifdef DEBUGGER
532
+			S9xTraceFormattedMessage("*** WRAM Refresh  HC:%04d", CPU.Cycles);
533
+		#endif
534
+
535
+			CPU.PrevCycles = CPU.Cycles;
536
+			CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
537
+			S9xCheckInterrupts();
538
+
539
+			S9xReschedule();
540
+
541
+			break;
542
+	}
543
+
544
+#ifdef DEBUGGER
545
+	if (Settings.TraceHCEvent)
546
+		S9xTraceFormattedMessage("--- HC event rescheduled (%s)  expected HC:%04d  current  HC:%04d",
547
+			eventname[CPU.WhichEvent], CPU.NextEvent, CPU.Cycles);
548
+#endif
549
+}