Browse code

[SNSF] Replaced most uses of fill/copy with fill_n/copy_n, and a few other minor code cleanups.

Naram Qashat authored on 2013/05/27 22:34:22
Showing 1 changed files
... ...
@@ -229,15 +229,11 @@ void S9xSetPPU(uint8_t Byte, uint16_t Address)
229 229
 		// write_port will run the APU until given clock before writing value
230 230
 		S9xAPUWritePort(Address & 3, Byte);
231 231
 	else if (Address <= 0x2183)
232
-	{
233 232
 		switch (Address)
234 233
 		{
235 234
 			case 0x2100: // INIDISP
236
-				if (Byte != Memory.FillRAM[0x2100])
237
-				{
238
-					if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80))
239
-						PPU.ForcedBlanking = !!((Byte >> 7) & 1);
240
-				}
235
+				if (Byte != Memory.FillRAM[0x2100] && (Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80))
236
+					PPU.ForcedBlanking = !!((Byte >> 7) & 1);
241 237
 
242 238
 				if ((Memory.FillRAM[0x2100] & 0x80) && CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)
243 239
 				{
... ...
@@ -434,10 +430,7 @@ void S9xSetPPU(uint8_t Byte, uint16_t Address)
434 430
 					PPU.WRAM |= Byte << 16;
435 431
 					PPU.WRAM &= 0x1ffff;
436 432
 				}
437
-
438
-				break;
439 433
 		}
440
-	}
441 434
 
442 435
 	Memory.FillRAM[Address] = Byte;
443 436
 }
... ...
@@ -658,7 +651,7 @@ void S9xSetCPU(uint8_t Byte, uint16_t Address)
658 651
 				DMA[d].UnusedBit43x0 = !!(Byte & 0x20);
659 652
 				DMA[d].AAddressDecrement = !!(Byte & 0x10);
660 653
 				DMA[d].AAddressFixed = !!(Byte & 0x08);
661
-				DMA[d].TransferMode = (Byte & 7);
654
+				DMA[d].TransferMode = Byte & 7;
662 655
 				return;
663 656
 
664 657
 			case 0x1: // 0x43x1: BBADx
... ...
@@ -775,9 +768,9 @@ void S9xSetCPU(uint8_t Byte, uint16_t Address)
775 768
 				uint16_t div = Byte ? a / Byte : 0xffff;
776 769
 				uint16_t rem = Byte ? a % Byte : a;
777 770
 				// FIXME: The update occurs 16 machine cycles after $4206 is set.
778
-				Memory.FillRAM[0x4214] = static_cast<uint8_t>(div);
771
+				Memory.FillRAM[0x4214] = div & 0xff;
779 772
 				Memory.FillRAM[0x4215] = div >> 8;
780
-				Memory.FillRAM[0x4216] = static_cast<uint8_t>(rem);
773
+				Memory.FillRAM[0x4216] = rem & 0xff;
781 774
 				Memory.FillRAM[0x4217] = rem >> 8;
782 775
 				break;
783 776
 			}
... ...
@@ -844,12 +837,7 @@ void S9xSetCPU(uint8_t Byte, uint16_t Address)
844 837
 
845 838
 			case 0x420d: // MEMSEL
846 839
 				if ((Byte & 1) != (Memory.FillRAM[0x420d] & 1))
847
-				{
848
-					if (Byte & 1)
849
-						CPU.FastROMSpeed = ONE_CYCLE;
850
-					else
851
-						CPU.FastROMSpeed = SLOW_ONE_CYCLE;
852
-				}
840
+					CPU.FastROMSpeed = Byte & 1 ? ONE_CYCLE : SLOW_ONE_CYCLE;
853 841
 
854 842
 				break;
855 843
 
... ...
@@ -948,8 +936,7 @@ uint8_t S9xGetCPU(uint16_t Address)
948 936
 
949 937
 			case 0x4211: // TIMEUP
950 938
 				byte = CPU.IRQLine ? 0x80 : 0;
951
-				CPU.IRQLine = false;
952
-				CPU.IRQTransition = false;
939
+				CPU.IRQLine = CPU.IRQTransition = false;
953 940
 				return byte | (OpenBus & 0x7f);
954 941
 
955 942
 			case 0x4212: // HVBJOY
... ...
@@ -1011,7 +998,7 @@ void S9xSoftResetPPU()
1011 998
 	PPU.OAMPriorityRotation = false;
1012 999
 	PPU.OAMFlip = 0;
1013 1000
 	PPU.OAMWriteRegister = 0;
1014
-	std::fill(&PPU.OAMData[0], &PPU.OAMData[512 + 32], 0);
1001
+	std::fill_n(&PPU.OAMData[0], sizeof(PPU.OAMData), 0);
1015 1002
 
1016 1003
 	PPU.FirstSprite = 0;
1017 1004
 
... ...
@@ -1038,12 +1025,12 @@ void S9xSoftResetPPU()
1038 1025
 	IPPU.Interlace = false;
1039 1026
 
1040 1027
 	for (int c = 0; c < 0x8000; c += 0x100)
1041
-		std::fill(&Memory.FillRAM[c], &Memory.FillRAM[c + 0x100], c >> 8);
1042
-	std::fill(&Memory.FillRAM[0x2100], &Memory.FillRAM[0x2200], 0);
1043
-	std::fill(&Memory.FillRAM[0x4200], &Memory.FillRAM[0x4300], 0);
1044
-	std::fill(&Memory.FillRAM[0x4000], &Memory.FillRAM[0x4100], 0);
1028
+		std::fill_n(&Memory.FillRAM[c], 0x100, c >> 8);
1029
+	std::fill_n(&Memory.FillRAM[0x2100], 0x0100, 0);
1030
+	std::fill_n(&Memory.FillRAM[0x4200], 0x0100, 0);
1031
+	std::fill_n(&Memory.FillRAM[0x4000], 0x0100, 0);
1045 1032
 	// For BS Suttehakkun 2...
1046
-	std::fill(&Memory.FillRAM[0x1000], &Memory.FillRAM[0x2000], 0);
1033
+	std::fill_n(&Memory.FillRAM[0x1000], 0x1000, 0);
1047 1034
 
1048 1035
 	Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = 0xff;
1049 1036
 }
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
... ...
@@ -175,147 +175,47 @@
175 175
   Nintendo Co., Limited and its subsidiary companies.
176 176
  ***********************************************************************************/
177 177
 
178
+#include <algorithm>
178 179
 #include "snes9x.h"
179 180
 #include "memmap.h"
180 181
 #include "dma.h"
181 182
 #include "apu/apu.h"
182
-//#include "fxemu.h"
183 183
 #include "sdd1.h"
184
-//#include "srtc.h"
185
-//#include "controls.h"
186
-//#include "movie.h"
187
-//#include "display.h"
188
-#ifdef NETPLAY_SUPPORT
189
-#include "netplay.h"
190
-#endif
191
-#ifdef DEBUGGER
192
-#include "debug.h"
193
-#include "missing.h"
194
-#endif
195
-
196
-extern uint8_t	*HDMAMemPointers[8];
197
-
198
-static inline void S9xLatchCounters (bool force)
199
-{
200
-	if (force || (Memory.FillRAM[0x4213] & 0x80))
201
-	{
202
-		// Latch h and v counters, like the gun
203
-	#ifdef DEBUGGER
204
-		missing.h_v_latch = 1;
205
-	#endif
206
-
207
-		PPU.HVBeamCounterLatched = 1;
208
-		PPU.VBeamPosLatched = (uint16_t) CPU.V_Counter;
209
-
210
-		// From byuu:
211
-		// All dots are 4 cycles long, except dots 322 and 326. dots 322 and 326 are 6 cycles long.
212
-		// This holds true for all scanlines except scanline 240 on non-interlace odd frames.
213
-		// The reason for this is because this scanline is only 1360 cycles long,
214
-		// instead of 1364 like all other scanlines.
215
-		// This makes the effective range of hscan_pos 0-339 at all times.
216
-		int32_t	hc = CPU.Cycles;
217
-
218
-		if (Timings.H_Max == Timings.H_Max_Master) // 1364
219
-		{
220
-			if (hc >= 1292)
221
-				hc -= (ONE_DOT_CYCLE / 2);
222
-			if (hc >= 1308)
223
-				hc -= (ONE_DOT_CYCLE / 2);
224
-		}
225
-
226
-		PPU.HBeamPosLatched = (uint16_t) (hc / ONE_DOT_CYCLE);
227 184
 
228
-		Memory.FillRAM[0x213f] |= 0x40;
229
-	}
230
-
231
-	if (CPU.V_Counter >  PPU.GunVLatch || (CPU.V_Counter == PPU.GunVLatch && CPU.Cycles >= PPU.GunHLatch * ONE_DOT_CYCLE))
232
-		PPU.GunVLatch = 1000;
233
-}
234
-
235
-static inline void S9xTryGunLatch (bool force)
236
-{
237
-	if (CPU.V_Counter >  PPU.GunVLatch || (CPU.V_Counter == PPU.GunVLatch && CPU.Cycles >= PPU.GunHLatch * ONE_DOT_CYCLE))
238
-	{
239
-		if (force || (Memory.FillRAM[0x4213] & 0x80))
240
-		{
241
-		#ifdef DEBUGGER
242
-			missing.h_v_latch = 1;
243
-		#endif
244
-
245
-			PPU.HVBeamCounterLatched = 1;
246
-			PPU.VBeamPosLatched = (uint16_t) PPU.GunVLatch;
247
-			PPU.HBeamPosLatched = (uint16_t) PPU.GunHLatch;
248
-
249
-			Memory.FillRAM[0x213f] |= 0x40;
250
-		}
251
-
252
-		PPU.GunVLatch = 1000;
253
-	}
254
-}
185
+extern uint8_t *HDMAMemPointers[8];
255 186
 
256 187
 void S9xUpdateHVTimerPosition()
257 188
 {
258 189
 	PPU.HTimerPosition = PPU.IRQHBeamPos * ONE_DOT_CYCLE + Timings.IRQTriggerCycles;
259
-	if (Timings.H_Max == Timings.H_Max_Master)	// 1364
190
+	if (Timings.H_Max == Timings.H_Max_Master) // 1364
260 191
 	{
261 192
 		if (PPU.IRQHBeamPos > 322)
262
-			PPU.HTimerPosition += (ONE_DOT_CYCLE / 2);
193
+			PPU.HTimerPosition += ONE_DOT_CYCLE / 2;
263 194
 		if (PPU.IRQHBeamPos > 326)
264
-			PPU.HTimerPosition += (ONE_DOT_CYCLE / 2);
195
+			PPU.HTimerPosition += ONE_DOT_CYCLE / 2;
265 196
 	}
266 197
 
267 198
 	PPU.VTimerPosition = PPU.IRQVBeamPos;
268 199
 
269
-	if ((PPU.HTimerPosition >= Timings.H_Max) && (PPU.IRQHBeamPos < 340))
200
+	if (PPU.HTimerPosition >= Timings.H_Max && PPU.IRQHBeamPos < 340)
270 201
 	{
271 202
 		PPU.HTimerPosition -= Timings.H_Max;
272
-		PPU.VTimerPosition++;
203
+		++PPU.VTimerPosition;
273 204
 		// FIXME
274 205
 		if (PPU.VTimerPosition >= Timings.V_Max)
275 206
 			PPU.VTimerPosition = 0;
276 207
 	}
277
-
278
-#ifdef DEBUGGER
279
-	S9xTraceFormattedMessage("--- IRQ Timer set  HTimer:%d Pos:%04d  VTimer:%d Pos:%03d",
280
-		PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition);
281
-#endif
282 208
 }
283 209
 
284
-/*void S9xFixColourBrightness()
285
-{
286
-	IPPU.XB = mul_brightness[PPU.Brightness];
287
-
288
-	for (int i = 0; i < 256; i++)
289
-	{
290
-		IPPU.Red[i]   = IPPU.XB[(PPU.CGDATA[i])       & 0x1f];
291
-		IPPU.Green[i] = IPPU.XB[(PPU.CGDATA[i] >>  5) & 0x1f];
292
-		IPPU.Blue[i]  = IPPU.XB[(PPU.CGDATA[i] >> 10) & 0x1f];
293
-		IPPU.ScreenColors[i] = BUILD_PIXEL(IPPU.Red[i], IPPU.Green[i], IPPU.Blue[i]);
294
-	}
295
-}*/
296
-
297
-void S9xSetPPU (uint8_t Byte, uint16_t Address)
210
+void S9xSetPPU(uint8_t Byte, uint16_t Address)
298 211
 {
299 212
 	// MAP_PPU: $2000-$3FFF
300 213
 
301 214
 	if (CPU.InDMAorHDMA)
302 215
 	{
303 216
 		if (CPU.CurrentDMAorHDMAChannel >= 0 && DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer)
304
-		{
305 217
 			// S9xSetPPU() is called to write to DMA[].AAddress
306
-			if ((Address & 0xff00) == 0x2100)
307
-			{
308
-				// Cannot access to Address Bus B ($2100-$21ff) via (H)DMA
309
-				return;
310
-			}
311
-			else
312
-			{
313
-				// 0x2000-0x3FFF is connected to Address Bus A
314
-				// SA1, SuperFX and SRTC are mapped here
315
-				// I don't bother for now...
316
-				return;
317
-			}
318
-		}
218
+			return;
319 219
 		else
320 220
 		{
321 221
 			// S9xSetPPU() is called to read from $21xx
... ...
@@ -325,39 +225,18 @@ void S9xSetPPU (uint8_t Byte, uint16_t Address)
325 225
 		}
326 226
 	}
327 227
 
328
-#ifdef DEBUGGER
329
-	if (CPU.InHDMA)
330
-		S9xTraceFormattedMessage("--- HDMA PPU %04X -> %02X", Address, Byte);
331
-#endif
332
-
333 228
 	if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3
334 229
 		// write_port will run the APU until given clock before writing value
335 230
 		S9xAPUWritePort(Address & 3, Byte);
336
-	else
337
-	if (Address <= 0x2183)
231
+	else if (Address <= 0x2183)
338 232
 	{
339 233
 		switch (Address)
340 234
 		{
341 235
 			case 0x2100: // INIDISP
342 236
 				if (Byte != Memory.FillRAM[0x2100])
343 237
 				{
344
-					//FLUSH_REDRAW();
345
-
346
-					if (PPU.Brightness != (Byte & 0xf))
347
-					{
348
-						IPPU.ColorsChanged = true;
349
-						IPPU.DirectColourMapsNeedRebuild = true;
350
-						PPU.Brightness = Byte & 0xf;
351
-						//S9xFixColourBrightness();
352
-						if (PPU.Brightness > IPPU.MaxBrightness)
353
-							IPPU.MaxBrightness = PPU.Brightness;
354
-					}
355
-
356 238
 					if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80))
357
-					{
358
-						IPPU.ColorsChanged = true;
359
-						PPU.ForcedBlanking = (Byte >> 7) & 1;
360
-					}
239
+						PPU.ForcedBlanking = !!((Byte >> 7) & 1);
361 240
 				}
362 241
 
363 242
 				if ((Memory.FillRAM[0x2100] & 0x80) && CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)
... ...
@@ -368,72 +247,34 @@ void S9xSetPPU (uint8_t Byte, uint16_t Address)
368 247
 					if (PPU.OAMPriorityRotation)
369 248
 						tmp = (PPU.OAMAddr & 0xfe) >> 1;
370 249
 					if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
371
-					{
372 250
 						PPU.FirstSprite = tmp;
373
-						IPPU.OBJChanged = true;
374
-					}
375 251
 
376 252
 					PPU.OAMFlip = 0;
377 253
 				}
378 254
 
379 255
 				break;
380 256
 
381
-			case 0x2101: // OBSEL
382
-				if (Byte != Memory.FillRAM[0x2101])
383
-				{
384
-					//FLUSH_REDRAW();
385
-					PPU.OBJNameBase = (Byte & 3) << 14;
386
-					PPU.OBJNameSelect = ((Byte >> 3) & 3) << 13;
387
-					PPU.OBJSizeSelect = (Byte >> 5) & 7;
388
-					IPPU.OBJChanged = true;
389
-				}
390
-
391
-				break;
392
-
393 257
 			case 0x2102: // OAMADDL
394 258
 				PPU.OAMAddr = ((Memory.FillRAM[0x2103] & 1) << 8) | Byte;
395 259
 				PPU.OAMFlip = 2;
396
-				PPU.OAMReadFlip = 0;
397 260
 				PPU.SavedOAMAddr = PPU.OAMAddr;
398 261
 				if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
399
-				{
400 262
 					PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1;
401
-					IPPU.OBJChanged = true;
402
-				#ifdef DEBUGGER
403
-					missing.sprite_priority_rotation = 1;
404
-				#endif
405
-				}
406 263
 
407 264
 				break;
408 265
 
409 266
 			case 0x2103: // OAMADDH
410 267
 				PPU.OAMAddr = ((Byte & 1) << 8) | Memory.FillRAM[0x2102];
411
-				PPU.OAMPriorityRotation = (Byte & 0x80) ? 1 : 0;
268
+				PPU.OAMPriorityRotation = !!(Byte & 0x80);
412 269
 				if (PPU.OAMPriorityRotation)
413 270
 				{
414 271
 					if (PPU.FirstSprite != (PPU.OAMAddr >> 1))
415
-					{
416 272
 						PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1;
417
-						IPPU.OBJChanged = true;
418
-					#ifdef DEBUGGER
419
-						missing.sprite_priority_rotation = 1;
420
-					#endif
421
-					}
422
-				}
423
-				else
424
-				{
425
-					if (PPU.FirstSprite != 0)
426
-					{
427
-						PPU.FirstSprite = 0;
428
-						IPPU.OBJChanged = true;
429
-					#ifdef DEBUGGER
430
-						missing.sprite_priority_rotation = 1;
431
-					#endif
432
-					}
433 273
 				}
274
+				else if (PPU.FirstSprite)
275
+					PPU.FirstSprite = 0;
434 276
 
435 277
 				PPU.OAMFlip = 0;
436
-				PPU.OAMReadFlip = 0;
437 278
 				PPU.SavedOAMAddr = PPU.OAMAddr;
438 279
 
439 280
 				break;
... ...
@@ -444,176 +285,45 @@ void S9xSetPPU (uint8_t Byte, uint16_t Address)
444 285
 
445 286
 			case 0x2105: // BGMODE
446 287
 				if (Byte != Memory.FillRAM[0x2105])
447
-				{
448
-					//FLUSH_REDRAW();
449
-					PPU.BG[0].BGSize = (Byte >> 4) & 1;
450
-					PPU.BG[1].BGSize = (Byte >> 5) & 1;
451
-					PPU.BG[2].BGSize = (Byte >> 6) & 1;
452
-					PPU.BG[3].BGSize = (Byte >> 7) & 1;
453
-					PPU.BGMode = Byte & 7;
454
-					// BJ: BG3Priority only takes effect if BGMode == 1 and the bit is set
455
-					PPU.BG3Priority = ((Byte & 0x0f) == 0x09);
456
-					IPPU.Interlace = Memory.FillRAM[0x2133] & 1;
457
-				#ifdef DEBUGGER
458
-					missing.modes[PPU.BGMode] = 1;
459
-				#endif
460
-				}
461
-
462
-				break;
463
-
464
-			case 0x2106: // MOSAIC
465
-				if (Byte != Memory.FillRAM[0x2106])
466
-				{
467
-					//FLUSH_REDRAW();
468
-					PPU.MosaicStart = CPU.V_Counter;
469
-					if (PPU.MosaicStart > PPU.ScreenHeight)
470
-						PPU.MosaicStart = 0;
471
-					PPU.Mosaic = (Byte >> 4) + 1;
472
-					PPU.BGMosaic[0] = (Byte & 1);
473
-					PPU.BGMosaic[1] = !!(Byte & 2);
474
-					PPU.BGMosaic[2] = !!(Byte & 4);
475
-					PPU.BGMosaic[3] = !!(Byte & 8);
476
-				#ifdef DEBUGGER
477
-					if ((Byte & 0xf0) && (Byte & 0x0f))
478
-						missing.mosaic = 1;
479
-				#endif
480
-				}
481
-
482
-				break;
483
-
484
-			case 0x2107: // BG1SC
485
-				if (Byte != Memory.FillRAM[0x2107])
486
-				{
487
-					//FLUSH_REDRAW();
488
-					PPU.BG[0].SCSize = Byte & 3;
489
-					PPU.BG[0].SCBase = (Byte & 0x7c) << 8;
490
-				}
491
-
492
-				break;
493
-
494
-			case 0x2108: // BG2SC
495
-				if (Byte != Memory.FillRAM[0x2108])
496
-				{
497
-					//FLUSH_REDRAW();
498
-					PPU.BG[1].SCSize = Byte & 3;
499
-					PPU.BG[1].SCBase = (Byte & 0x7c) << 8;
500
-				}
501
-
502
-				break;
503
-
504
-			case 0x2109: // BG3SC
505
-				if (Byte != Memory.FillRAM[0x2109])
506
-				{
507
-					//FLUSH_REDRAW();
508
-					PPU.BG[2].SCSize = Byte & 3;
509
-					PPU.BG[2].SCBase = (Byte & 0x7c) << 8;
510
-				}
511
-
512
-				break;
513
-
514
-			case 0x210a: // BG4SC
515
-				if (Byte != Memory.FillRAM[0x210a])
516
-				{
517
-					//FLUSH_REDRAW();
518
-					PPU.BG[3].SCSize = Byte & 3;
519
-					PPU.BG[3].SCBase = (Byte & 0x7c) << 8;
520
-				}
521
-
522
-				break;
523
-
524
-			case 0x210b: // BG12NBA
525
-				if (Byte != Memory.FillRAM[0x210b])
526
-				{
527
-					//FLUSH_REDRAW();
528
-					PPU.BG[0].NameBase = (Byte & 7) << 12;
529
-					PPU.BG[1].NameBase = ((Byte >> 4) & 7) << 12;
530
-				}
531
-
532
-				break;
533
-
534
-			case 0x210c: // BG34NBA
535
-				if (Byte != Memory.FillRAM[0x210c])
536
-				{
537
-					//FLUSH_REDRAW();
538
-					PPU.BG[2].NameBase = (Byte & 7) << 12;
539
-					PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12;
540
-				}
288
+					IPPU.Interlace = !!(Memory.FillRAM[0x2133] & 1);
541 289
 
542 290
 				break;
543 291
 
544 292
 			case 0x210d: // BG1HOFS, M7HOFS
545
-				PPU.BG[0].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[0].HOffset >> 8) & 7);
546
-				PPU.M7HOFS = (Byte << 8) | PPU.M7byte;
547
-				PPU.BGnxOFSbyte = Byte;
548 293
 				PPU.M7byte = Byte;
549 294
 				break;
550 295
 
551 296
 			case 0x210e: // BG1VOFS, M7VOFS
552
-				PPU.BG[0].VOffset = (Byte << 8) | PPU.BGnxOFSbyte;
553
-				PPU.M7VOFS = (Byte << 8) | PPU.M7byte;
554
-				PPU.BGnxOFSbyte = Byte;
555 297
 				PPU.M7byte = Byte;
556 298
 				break;
557 299
 
558
-			case 0x210f: // BG2HOFS
559
-				PPU.BG[1].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[1].HOffset >> 8) & 7);
560
-				PPU.BGnxOFSbyte = Byte;
561
-				break;
562
-
563
-			case 0x2110: // BG2VOFS
564
-				PPU.BG[1].VOffset = (Byte << 8) | PPU.BGnxOFSbyte;
565
-				PPU.BGnxOFSbyte = Byte;
566
-				break;
567
-
568
-			case 0x2111: // BG3HOFS
569
-				PPU.BG[2].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[2].HOffset >> 8) & 7);
570
-				PPU.BGnxOFSbyte = Byte;
571
-				break;
572
-
573
-			case 0x2112: // BG3VOFS
574
-				PPU.BG[2].VOffset = (Byte << 8) | PPU.BGnxOFSbyte;
575
-				PPU.BGnxOFSbyte = Byte;
576
-				break;
577
-
578
-			case 0x2113: // BG4HOFS
579
-				PPU.BG[3].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[3].HOffset >> 8) & 7);
580
-				PPU.BGnxOFSbyte = Byte;
581
-				break;
582
-
583
-			case 0x2114: // BG4VOFS
584
-				PPU.BG[3].VOffset = (Byte << 8) | PPU.BGnxOFSbyte;
585
-				PPU.BGnxOFSbyte = Byte;
586
-				break;
587
-
588 300
 			case 0x2115: // VMAIN
589
-				PPU.VMA.High = (Byte & 0x80) == 0 ? false : true;
301
+				PPU.VMA.High = !!(Byte & 0x80);
590 302
 				switch (Byte & 3)
591 303
 				{
592
-					case 0: PPU.VMA.Increment = 1;   break;
593
-					case 1: PPU.VMA.Increment = 32;  break;
594
-					case 2: PPU.VMA.Increment = 128; break;
595
-					case 3: PPU.VMA.Increment = 128; break;
304
+					case 0:
305
+						PPU.VMA.Increment = 1;
306
+						break;
307
+					case 1:
308
+						PPU.VMA.Increment = 32;
309
+						break;
310
+					case 2:
311
+					case 3:
312
+						PPU.VMA.Increment = 128;
596 313
 				}
597 314
 
598 315
 				if (Byte & 0x0c)
599 316
 				{
600
-					static uint16_t Shift[4]    = { 0, 5, 6, 7 };
601
-					static uint16_t IncCount[4] = { 0, 32, 64, 128 };
317
+					static const uint16_t Shift[] = { 0, 5, 6, 7 };
318
+					static const uint16_t IncCount[] = { 0, 32, 64, 128 };
602 319
 
603 320
 					uint8_t i = (Byte & 0x0c) >> 2;
604 321
 					PPU.VMA.FullGraphicCount = IncCount[i];
605 322
 					PPU.VMA.Mask1 = IncCount[i] * 8 - 1;
606 323
 					PPU.VMA.Shift = Shift[i];
607
-				#ifdef DEBUGGER
608
-					missing.vram_full_graphic_inc = (Byte & 0x0c) >> 2;
609
-				#endif
610 324
 				}
611 325
 				else
612 326
 					PPU.VMA.FullGraphicCount = 0;
613
-			#ifdef DEBUGGER
614
-				if (Byte & 3)
615
-					missing.vram_inc = Byte & 3;
616
-			#endif
617 327
 				break;
618 328
 
619 329
 			case 0x2116: // VMADDL
... ...
@@ -625,10 +335,10 @@ void S9xSetPPU (uint8_t Byte, uint16_t Address)
625 335
 					uint32_t addr = PPU.VMA.Address;
626 336
 					uint32_t rem = addr & PPU.VMA.Mask1;
627 337
 					uint32_t address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
628
-					IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff));
338
+					IPPU.VRAMReadBuffer = READ_WORD(&Memory.VRAM[(address << 1) & 0xffff]);
629 339
 				}
630 340
 				else
631
-					IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
341
+					IPPU.VRAMReadBuffer = READ_WORD(&Memory.VRAM[(PPU.VMA.Address << 1) & 0xffff]);
632 342
 
633 343
 				break;
634 344
 
... ...
@@ -641,10 +351,10 @@ void S9xSetPPU (uint8_t Byte, uint16_t Address)
641 351
 					uint32_t addr = PPU.VMA.Address;
642 352
 					uint32_t rem = addr & PPU.VMA.Mask1;
643 353
 					uint32_t address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
644
-					IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff));
354
+					IPPU.VRAMReadBuffer = READ_WORD(&Memory.VRAM[(address << 1) & 0xffff]);
645 355
 				}
646 356
 				else
647
-					IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
357
+					IPPU.VRAMReadBuffer = READ_WORD(&Memory.VRAM[(PPU.VMA.Address << 1) & 0xffff]);
648 358
 
649 359
 				break;
650 360
 
... ...
@@ -656,19 +366,6 @@ void S9xSetPPU (uint8_t Byte, uint16_t Address)
656 366
 				REGISTER_2119(Byte);
657 367
 				break;
658 368
 
659
-			case 0x211a: // M7SEL
660
-				if (Byte != Memory.FillRAM[0x211a])
661
-				{
662
-					//FLUSH_REDRAW();
663
-					PPU.Mode7Repeat = Byte >> 6;
664
-					if (PPU.Mode7Repeat == 1)
665
-						PPU.Mode7Repeat = 0;
666
-					PPU.Mode7VFlip = !!((Byte & 2) >> 1);
667
-					PPU.Mode7HFlip = Byte & 1;
668
-				}
669
-
670
-				break;
671
-
672 369
 			case 0x211b: // M7A
673 370
 				PPU.MatrixA = PPU.M7byte | (Byte << 8);
674 371
 				PPU.Need16x8Mulitply = true;
... ...
@@ -682,330 +379,31 @@ void S9xSetPPU (uint8_t Byte, uint16_t Address)
682 379
 				break;
683 380
 
684 381
 			case 0x211d: // M7C
685
-				PPU.MatrixC = PPU.M7byte | (Byte << 8);
686
-				PPU.M7byte = Byte;
687
-				break;
688
-
689 382
 			case 0x211e: // M7D
690
-				PPU.MatrixD = PPU.M7byte | (Byte << 8);
691
-				PPU.M7byte = Byte;
692
-				break;
693
-
694 383
 			case 0x211f: // M7X
695
-				PPU.CentreX = PPU.M7byte | (Byte << 8);
696
-				PPU.M7byte = Byte;
697
-				break;
698
-
699 384
 			case 0x2120: // M7Y
700
-				PPU.CentreY = PPU.M7byte | (Byte << 8);
701 385
 				PPU.M7byte = Byte;
702 386
 				break;
703 387
 
704 388
 			case 0x2121: // CGADD
705
-				PPU.CGFLIP = 0;
706
-				PPU.CGFLIPRead = 0;
389
+				PPU.CGFLIPRead = false;
707 390
 				PPU.CGADD = Byte;
708 391
 				break;
709 392
 
710
-			/*case 0x2122: // CGDATA
711
-				REGISTER_2122(Byte);
712
-				break;*/
713
-
714
-			case 0x2123: // W12SEL
715
-				if (Byte != Memory.FillRAM[0x2123])
716
-				{
717
-					//FLUSH_REDRAW();
718
-					PPU.ClipWindow1Enable[0] = !!(Byte & 0x02);
719
-					PPU.ClipWindow1Enable[1] = !!(Byte & 0x20);
720
-					PPU.ClipWindow2Enable[0] = !!(Byte & 0x08);
721
-					PPU.ClipWindow2Enable[1] = !!(Byte & 0x80);
722
-					PPU.ClipWindow1Inside[0] = !(Byte & 0x01);
723
-					PPU.ClipWindow1Inside[1] = !(Byte & 0x10);
724
-					PPU.ClipWindow2Inside[0] = !(Byte & 0x04);
725
-					PPU.ClipWindow2Inside[1] = !(Byte & 0x40);
726
-					PPU.RecomputeClipWindows = true;
727
-				#ifdef DEBUGGER
728
-					if (Byte & 0x80)
729
-						missing.window2[1] = 1;
730
-					if (Byte & 0x20)
731
-						missing.window1[1] = 1;
732
-					if (Byte & 0x08)
733
-						missing.window2[0] = 1;
734
-					if (Byte & 0x02)
735
-						missing.window1[0] = 1;
736
-				#endif
737
-				}
738
-
739
-				break;
740
-
741
-			case 0x2124: // W34SEL
742
-				if (Byte != Memory.FillRAM[0x2124])
743
-				{
744
-					//FLUSH_REDRAW();
745
-					PPU.ClipWindow1Enable[2] = !!(Byte & 0x02);
746
-					PPU.ClipWindow1Enable[3] = !!(Byte & 0x20);
747
-					PPU.ClipWindow2Enable[2] = !!(Byte & 0x08);
748
-					PPU.ClipWindow2Enable[3] = !!(Byte & 0x80);
749
-					PPU.ClipWindow1Inside[2] = !(Byte & 0x01);
750
-					PPU.ClipWindow1Inside[3] = !(Byte & 0x10);
751
-					PPU.ClipWindow2Inside[2] = !(Byte & 0x04);
752
-					PPU.ClipWindow2Inside[3] = !(Byte & 0x40);
753
-					PPU.RecomputeClipWindows = true;
754
-				#ifdef DEBUGGER
755
-					if (Byte & 0x80)
756
-						missing.window2[3] = 1;
757
-					if (Byte & 0x20)
758
-						missing.window1[3] = 1;
759
-					if (Byte & 0x08)
760
-						missing.window2[2] = 1;
761
-					if (Byte & 0x02)
762
-						missing.window1[2] = 1;
763
-				#endif
764
-				}
765
-
766
-				break;
767
-
768
-			case 0x2125: // WOBJSEL
769
-				if (Byte != Memory.FillRAM[0x2125])
770
-				{
771
-					//FLUSH_REDRAW();
772
-					PPU.ClipWindow1Enable[4] = !!(Byte & 0x02);
773
-					PPU.ClipWindow1Enable[5] = !!(Byte & 0x20);
774
-					PPU.ClipWindow2Enable[4] = !!(Byte & 0x08);
775
-					PPU.ClipWindow2Enable[5] = !!(Byte & 0x80);
776
-					PPU.ClipWindow1Inside[4] = !(Byte & 0x01);
777
-					PPU.ClipWindow1Inside[5] = !(Byte & 0x10);
778
-					PPU.ClipWindow2Inside[4] = !(Byte & 0x04);
779
-					PPU.ClipWindow2Inside[5] = !(Byte & 0x40);
780
-					PPU.RecomputeClipWindows = true;
781
-				#ifdef DEBUGGER
782
-					if (Byte & 0x80)
783
-						missing.window2[5] = 1;
784
-					if (Byte & 0x20)
785
-						missing.window1[5] = 1;
786
-					if (Byte & 0x08)
787
-						missing.window2[4] = 1;
788
-					if (Byte & 0x02)
789
-						missing.window1[4] = 1;
790
-				#endif
791
-				}
792
-
793
-				break;
794
-
795
-			case 0x2126: // WH0
796
-				if (Byte != Memory.FillRAM[0x2126])
797
-				{
798
-					//FLUSH_REDRAW();
799
-					PPU.Window1Left = Byte;
800
-					PPU.RecomputeClipWindows = true;
801
-				}
802
-
803
-				break;
804
-
805
-			case 0x2127: // WH1
806
-				if (Byte != Memory.FillRAM[0x2127])
807
-				{
808
-					//FLUSH_REDRAW();
809
-					PPU.Window1Right = Byte;
810
-					PPU.RecomputeClipWindows = true;
811
-				}
812
-
813
-				break;
814
-
815
-			case 0x2128: // WH2
816
-				if (Byte != Memory.FillRAM[0x2128])
817
-				{
818
-					//FLUSH_REDRAW();
819
-					PPU.Window2Left = Byte;
820
-					PPU.RecomputeClipWindows = true;
821
-				}
822
-
823
-				break;
824
-
825
-			case 0x2129: // WH3
826
-				if (Byte != Memory.FillRAM[0x2129])
827
-				{
828
-					//FLUSH_REDRAW();
829
-					PPU.Window2Right = Byte;
830
-					PPU.RecomputeClipWindows = true;
831
-				}
832
-
833
-				break;
834
-
835
-			case 0x212a: // WBGLOG
836
-				if (Byte != Memory.FillRAM[0x212a])
837
-				{
838
-					//FLUSH_REDRAW();
839
-					PPU.ClipWindowOverlapLogic[0] = (Byte & 0x03);
840
-					PPU.ClipWindowOverlapLogic[1] = (Byte & 0x0c) >> 2;
841
-					PPU.ClipWindowOverlapLogic[2] = (Byte & 0x30) >> 4;
842
-					PPU.ClipWindowOverlapLogic[3] = (Byte & 0xc0) >> 6;
843
-					PPU.RecomputeClipWindows = true;
844
-				}
845
-
846
-				break;
847
-
848
-			case 0x212b: // WOBJLOG
849
-				if (Byte != Memory.FillRAM[0x212b])
850
-				{
851
-					//FLUSH_REDRAW();
852
-					PPU.ClipWindowOverlapLogic[4] = (Byte & 0x03);
853
-					PPU.ClipWindowOverlapLogic[5] = (Byte & 0x0c) >> 2;
854
-					PPU.RecomputeClipWindows = true;
855
-				}
856
-
857
-				break;
858
-
859
-			case 0x212c: // TM
860
-				if (Byte != Memory.FillRAM[0x212c])
861
-				{
862
-					//FLUSH_REDRAW();
863
-					PPU.RecomputeClipWindows = true;
864
-				}
865
-
866
-				break;
867
-
868
-			case 0x212d: // TS
869
-				if (Byte != Memory.FillRAM[0x212d])
870
-				{
871
-					//FLUSH_REDRAW();
872
-					PPU.RecomputeClipWindows = true;
873
-				#ifdef DEBUGGER
874
-					if (Byte & 0x1f)
875
-						missing.subscreen = 1;
876
-				#endif
877
-				}
878
-
879
-				break;
880
-
881
-			case 0x212e: // TMW
882
-				if (Byte != Memory.FillRAM[0x212e])
883
-				{
884
-					//FLUSH_REDRAW();
885
-					PPU.RecomputeClipWindows = true;
886
-				}
887
-
888
-				break;
889
-
890
-			case 0x212f: // TSW
891
-				if (Byte != Memory.FillRAM[0x212f])
892
-				{
893
-					//FLUSH_REDRAW();
894
-					PPU.RecomputeClipWindows = true;
895
-				}
896
-
897
-				break;
898
-
899
-			case 0x2130: // CGWSEL
900
-				if (Byte != Memory.FillRAM[0x2130])
901
-				{
902
-					//FLUSH_REDRAW();
903
-					PPU.RecomputeClipWindows = true;
904
-				#ifdef DEBUGGER
905
-					if ((Byte & 1) && (PPU.BGMode == 3 || PPU.BGMode == 4 || PPU.BGMode == 7))
906
-						missing.direct = 1;
907
-				#endif
908
-				}
909
-
910
-				break;
911
-
912
-			case 0x2131: // CGADSUB
913
-				if (Byte != Memory.FillRAM[0x2131])
914
-				{
915
-					//FLUSH_REDRAW();
916
-				#ifdef DEBUGGER
917
-					if (Byte & 0x80)
918
-					{
919
-						if (Memory.FillRAM[0x2130] & 0x02)
920
-							missing.subscreen_sub = 1;
921
-						else
922
-							missing.fixed_colour_sub = 1;
923
-					}
924
-					else
925
-					{
926
-						if (Memory.FillRAM[0x2130] & 0x02)
927
-							missing.subscreen_add = 1;
928
-						else
929
-							missing.fixed_colour_add = 1;
930
-					}
931
-				#endif
932
-				}
933
-
934
-				break;
935
-
936
-			case 0x2132: // COLDATA
937
-				if (Byte != Memory.FillRAM[0x2132])
938
-				{
939
-					//FLUSH_REDRAW();
940
-					if (Byte & 0x80)
941
-						PPU.FixedColourBlue  = Byte & 0x1f;
942
-					if (Byte & 0x40)
943
-						PPU.FixedColourGreen = Byte & 0x1f;
944
-					if (Byte & 0x20)
945
-						PPU.FixedColourRed   = Byte & 0x1f;
946
-				}
947
-
948
-				break;
949
-
950 393
 			case 0x2133: // SETINI
951 394
 				if (Byte != Memory.FillRAM[0x2133])
952 395
 				{
953
-					if ((Memory.FillRAM[0x2133] ^ Byte) & 8)
954
-					{
955
-						//FLUSH_REDRAW();
956
-						IPPU.PseudoHires = !!(Byte & 8);
957
-					}
958
-
959 396
 					if (Byte & 0x04)
960
-					{
961 397
 						PPU.ScreenHeight = SNES_HEIGHT_EXTENDED;
962
-						if (IPPU.DoubleHeightPixels)
963
-							IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1;
964
-						else
965
-							IPPU.RenderedScreenHeight = PPU.ScreenHeight;
966
-					#ifdef DEBUGGER
967
-						missing.lines_239 = 1;
968
-					#endif
969
-					}
970 398
 					else
971 399
 						PPU.ScreenHeight = SNES_HEIGHT;
972 400
 
973 401
 					if ((Memory.FillRAM[0x2133] ^ Byte) & 3)
974
-					{
975
-						//FLUSH_REDRAW();
976
-						if ((Memory.FillRAM[0x2133] ^ Byte) & 2)
977
-							IPPU.OBJChanged = true;
978
-						IPPU.Interlace = Byte & 1;
979
-						IPPU.InterlaceOBJ = !!(Byte & 2);
980
-					}
981
-				#ifdef DEBUGGER
982
-					if (Byte & 0x40)
983
-						missing.mode7_bgmode = 1;
984
-					if (Byte & 0x08)
985
-						missing.pseudo_512 = 1;
986
-					if (Byte & 0x02)
987
-						missing.sprite_double_height = 1;
988
-					if (Byte & 0x01)
989
-						missing.interlace = 1;
990
-				#endif
402
+						IPPU.Interlace = !!(Byte & 1);
991 403
 				}
992 404
 
993 405
 				break;
994 406
 
995
-			case 0x2134: // MPYL
996
-			case 0x2135: // MPYM
997
-			case 0x2136: // MPYH
998
-			case 0x2137: // SLHV
999
-			case 0x2138: // OAMDATAREAD
1000
-			case 0x2139: // VMDATALREAD
1001
-			case 0x213a: // VMDATAHREAD
1002
-			case 0x213b: // CGDATAREAD
1003
-			case 0x213c: // OPHCT
1004
-			case 0x213d: // OPVCT
1005
-			case 0x213e: // STAT77
1006
-			case 0x213f: // STAT78
1007
-				return;
1008
-
1009 407
 			case 0x2180: // WMDATA
1010 408
 				if (!CPU.InWRAMDMAorHDMA)
1011 409
 					REGISTER_2180(Byte);
... ...
@@ -1040,45 +438,11 @@ void S9xSetPPU (uint8_t Byte, uint16_t Address)
1040 438
 				break;
1041 439
 		}
1042 440
 	}
1043
-	/*else
1044
-	{
1045
-		if (Settings.SuperFX && Address >= 0x3000 && Address <= 0x32ff)
1046
-		{
1047
-			S9xSetSuperFX(Byte, Address);
1048
-			return;
1049
-		}
1050
-		else
1051
-		if (Settings.SA1     && Address >= 0x2200)
1052
-		{
1053
-			if (Address <= 0x23ff)
1054
-				S9xSetSA1(Byte, Address);
1055
-			else
1056
-				Memory.FillRAM[Address] = Byte;
1057
-			return;
1058
-		}
1059
-		else
1060
-		if (Settings.BS      && Address >= 0x2188 && Address <= 0x219f)
1061
-			S9xSetBSXPPU(Byte, Address);
1062
-		else
1063
-		if (Settings.SRTC    && Address == 0x2801)
1064
-			S9xSetSRTC(Byte, Address);
1065
-	#ifdef DEBUGGER
1066
-		else
1067
-		{
1068
-			missing.unknownppu_write = Address;
1069
-			if (Settings.TraceUnknownRegisters)
1070
-			{
1071
-				sprintf(String, "Unknown register write: $%02X->$%04X\n", Byte, Address);
1072
-				S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String);
1073
-			}
1074
-		}
1075
-	#endif
1076
-	}*/
1077 441
 
1078 442
 	Memory.FillRAM[Address] = Byte;
1079 443
 }
1080 444
 
1081
-uint8_t S9xGetPPU (uint16_t Address)
445
+uint8_t S9xGetPPU(uint16_t Address)
1082 446
 {
1083 447
 	// MAP_PPU: $2000-$3FFF
1084 448
 
... ...
@@ -1088,17 +452,8 @@ uint8_t S9xGetPPU (uint16_t Address)
1088 452
 	if (CPU.InDMAorHDMA)
1089 453
 	{
1090 454
 		if (CPU.CurrentDMAorHDMAChannel >= 0 && !DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer)
1091
-		{
1092 455
 			// S9xGetPPU() is called to read from DMA[].AAddress
1093
-			if ((Address & 0xff00) == 0x2100)
1094
-				// Cannot access to Address Bus B ($2100-$21FF) via (H)DMA
1095
-				return OpenBus;
1096
-			else
1097
-				// $2200-$3FFF are connected to Address Bus A
1098
-				// SA1, SuperFX and SRTC are mapped here
1099
-				// I don't bother for now...
1100
-				return OpenBus;
1101
-		}
456
+			return OpenBus;
1102 457
 		else
1103 458
 		{
1104 459
 			// S9xGetPPU() is called to write to $21xx
... ...
@@ -1111,10 +466,9 @@ uint8_t S9xGetPPU (uint16_t Address)
1111 466
 	if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3
1112 467
 		// read_port will run the APU until given APU time before reading value
1113 468
 		return S9xAPUReadPort(Address & 3);
1114
-	else
1115
-	if (Address <= 0x2183)
1116
-    {
1117
-		uint8_t	byte;
469
+	else if (Address <= 0x2183)
470
+	{
471
+		uint8_t byte;
1118 472
 
1119 473
 		switch (Address)
1120 474
 		{
... ...
@@ -1143,19 +497,15 @@ uint8_t S9xGetPPU (uint16_t Address)
1143 497
 			case 0x2136: // MPYH
1144 498
 				if (PPU.Need16x8Mulitply)
1145 499
 				{
1146
-					int32_t r = (int32_t) PPU.MatrixA * (int32_t) (PPU.MatrixB >> 8);
1147
-					Memory.FillRAM[0x2134] = (uint8_t) r;
1148
-					Memory.FillRAM[0x2135] = (uint8_t) (r >> 8);
1149
-					Memory.FillRAM[0x2136] = (uint8_t) (r >> 16);
500
+					int32_t r = static_cast<int32_t>(PPU.MatrixA) * static_cast<int32_t>(PPU.MatrixB >> 8);
501
+					Memory.FillRAM[0x2134] = static_cast<uint8_t>(r);
502
+					Memory.FillRAM[0x2135] = static_cast<uint8_t>(r >> 8);
503
+					Memory.FillRAM[0x2136] = static_cast<uint8_t>(r >> 16);
1150 504
 					PPU.Need16x8Mulitply = false;
1151 505
 				}
1152
-			#ifdef DEBUGGER
1153
-				missing.matrix_multiply = 1;
1154
-			#endif
1155 506
 				return (PPU.OpenBus1 = Memory.FillRAM[Address]);
1156 507
 
1157 508
 			case 0x2137: // SLHV
1158
-				S9xLatchCounters(0);
1159 509
 				return OpenBus;
1160 510
 
1161 511
 			case 0x2138: // OAMDATAREAD
... ...
@@ -1168,13 +518,7 @@ uint8_t S9xGetPPU (uint16_t Address)
1168 518
 						byte = PPU.OAMData[((PPU.OAMAddr & 0x10f) << 1) + 1];
1169 519
 						PPU.OAMAddr = (PPU.OAMAddr + 1) & 0x1ff;
1170 520
 						if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
1171
-						{
1172 521
 							PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1;
1173
-							IPPU.OBJChanged = true;
1174
-						#ifdef DEBUGGER
1175
-							missing.sprite_priority_rotation = 1;
1176
-						#endif
1177
-						}
1178 522
 					}
1179 523
 				}
1180 524
 				else
... ...
@@ -1186,20 +530,11 @@ uint8_t S9xGetPPU (uint16_t Address)
1186 530
 						byte = PPU.OAMData[(PPU.OAMAddr << 1) + 1];
1187 531
 						++PPU.OAMAddr;
1188 532
 						if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
1189
-						{
1190 533
 							PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1;
1191
-							IPPU.OBJChanged = true;
1192
-						#ifdef DEBUGGER
1193
-							missing.sprite_priority_rotation = 1;
1194
-						#endif
1195
-						}
1196 534
 					}
1197 535
 				}
1198 536
 
1199 537
 				PPU.OAMFlip ^= 1;
1200
-			#ifdef DEBUGGER
1201
-				missing.oam_read = 1;
1202
-			#endif
1203 538
 				return (PPU.OpenBus1 = byte);
1204 539
 
1205 540
 			case 0x2139: // VMDATALREAD
... ...
@@ -1211,17 +546,13 @@ uint8_t S9xGetPPU (uint16_t Address)
1211 546
 						uint32_t addr = PPU.VMA.Address;
1212 547
 						uint32_t rem = addr & PPU.VMA.Mask1;
1213 548
 						uint32_t address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
1214
-						IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff));
549
+						IPPU.VRAMReadBuffer = READ_WORD(&Memory.VRAM[(address << 1) & 0xffff]);
1215 550
 					}
1216 551
 					else
1217
-						IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
552
+						IPPU.VRAMReadBuffer = READ_WORD(&Memory.VRAM[(PPU.VMA.Address << 1) & 0xffff]);
1218 553
 
1219 554
 					PPU.VMA.Address += PPU.VMA.Increment;
1220 555
 				}
1221
-
1222
-			#ifdef DEBUGGER
1223
-				missing.vram_read = 1;
1224
-			#endif
1225 556
 				return (PPU.OpenBus1 = byte);
1226 557
 
1227 558
 			case 0x213a: // VMDATAHREAD
... ...
@@ -1233,16 +564,13 @@ uint8_t S9xGetPPU (uint16_t Address)
1233 564
 						uint32_t addr = PPU.VMA.Address;
1234 565
 						uint32_t rem = addr & PPU.VMA.Mask1;
1235 566
 						uint32_t address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
1236
-						IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff));
567
+						IPPU.VRAMReadBuffer = READ_WORD(&Memory.VRAM[(address << 1) & 0xffff]);
1237 568
 					}
1238 569
 					else
1239
-						IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
570
+						IPPU.VRAMReadBuffer = READ_WORD(&Memory.VRAM[(PPU.VMA.Address << 1) & 0xffff]);
1240 571
 
1241 572
 					PPU.VMA.Address += PPU.VMA.Increment;
1242 573
 				}
1243
-			#ifdef DEBUGGER
1244
-				missing.vram_read = 1;
1245
-			#endif
1246 574
 				return (PPU.OpenBus1 = byte);
1247 575
 
1248 576
 			case 0x213b: // CGDATAREAD
... ...
@@ -1250,44 +578,31 @@ uint8_t S9xGetPPU (uint16_t Address)
1250 578
 					byte = (PPU.OpenBus2 & 0x80) | ((PPU.CGDATA[PPU.CGADD++] >> 8) & 0x7f);
1251 579
 				else
1252 580
 					byte = PPU.CGDATA[PPU.CGADD] & 0xff;
1253
-				PPU.CGFLIPRead ^= 1;
1254
-			#ifdef DEBUGGER
1255
-				missing.cgram_read = 1;
1256
-			#endif
581
+				PPU.CGFLIPRead = !PPU.CGFLIPRead;
1257 582
 				return (PPU.OpenBus2 = byte);
1258 583
 
1259 584
 			case 0x213c: // OPHCT
1260
-				S9xTryGunLatch(false);
1261 585
 				if (PPU.HBeamFlip)
1262
-					byte = (PPU.OpenBus2 & 0xfe) | ((PPU.HBeamPosLatched >> 8) & 0x01);
586
+					byte = PPU.OpenBus2 & 0xfe;
1263 587
 				else
1264
-					byte = (uint8_t) PPU.HBeamPosLatched;
1265
-				PPU.HBeamFlip ^= 1;
1266
-			#ifdef DEBUGGER
1267
-				missing.h_counter_read = 1;
1268
-			#endif
588
+					byte = 0;
589
+				PPU.HBeamFlip = !PPU.HBeamFlip;
1269 590
 				return (PPU.OpenBus2 = byte);
1270 591
 
1271 592
 			case 0x213d: // OPVCT
1272
-				S9xTryGunLatch(false);
1273 593
 				if (PPU.VBeamFlip)
1274
-					byte = (PPU.OpenBus2 & 0xfe) | ((PPU.VBeamPosLatched >> 8) & 0x01);
594
+					byte = PPU.OpenBus2 & 0xfe;
1275 595
 				else
1276
-					byte = (uint8_t) PPU.VBeamPosLatched;
1277
-				PPU.VBeamFlip ^= 1;
1278
-			#ifdef DEBUGGER
1279
-				missing.v_counter_read = 1;
1280
-			#endif
596
+					byte = 0;
597
+				PPU.VBeamFlip = !PPU.VBeamFlip;
1281 598
 				return (PPU.OpenBus2 = byte);
1282 599
 
1283 600
 			case 0x213e: // STAT77
1284
-				//FLUSH_REDRAW();
1285
-				byte = (PPU.OpenBus1 & 0x10) | PPU.RangeTimeOver | Model->_5C77;
601
+				byte = (PPU.OpenBus1 & 0x10) | Model->_5C77;
1286 602
 				return (PPU.OpenBus1 = byte);
1287 603
 
1288 604
 			case 0x213f: // STAT78
1289
-				S9xTryGunLatch(false);
1290
-				PPU.VBeamFlip = PPU.HBeamFlip = 0;
605
+				PPU.VBeamFlip = PPU.HBeamFlip = false;
1291 606
 				byte = (PPU.OpenBus2 & 0x20) | (Memory.FillRAM[0x213f] & 0xc0) | (Settings.PAL ? 0x10 : 0) | Model->_5C78;
1292 607
 				Memory.FillRAM[0x213f] &= ~0x40;
1293 608
 				return (PPU.OpenBus2 = byte);
... ...
@@ -1300,9 +615,6 @@ uint8_t S9xGetPPU (uint16_t Address)
1300 615
 				}
1301 616
 				else
1302 617
 					byte = OpenBus;
1303
-			#ifdef DEBUGGER
1304
-				missing.wram_read = 1;
1305
-			#endif
1306 618
 				return byte;
1307 619
 
1308 620
 			default:
... ...
@@ -1310,19 +622,7 @@ uint8_t S9xGetPPU (uint16_t Address)
1310 622
 		}
1311 623
 	}
1312 624
 	else
1313
-    {
1314
-		/*if (Settings.SuperFX && Address >= 0x3000 && Address <= 0x32ff)
1315
-			return S9xGetSuperFX(Address);
1316
-		else
1317
-		if (Settings.SA1     && Address >= 0x2200)
1318
-			return S9xGetSA1(Address);
1319
-		else
1320
-		if (Settings.BS      && Address >= 0x2188 && Address <= 0x219f)
1321
-			return S9xGetBSXPPU(Address);
1322
-		else	
1323
-		if (Settings.SRTC    && Address == 0x2800)
1324
-			return S9xGetSRTC(Address);
1325
-		else*/
625
+	{
1326 626
 		switch (Address)
1327 627
 		{
1328 628
 			case 0x21c2:
... ...
@@ -1341,40 +641,24 @@ uint8_t S9xGetPPU (uint16_t Address)
1341 641
 	}
1342 642
 }
1343 643
 
1344
-void S9xSetCPU (uint8_t Byte, uint16_t Address)
644
+void S9xSetCPU(uint8_t Byte, uint16_t Address)
1345 645
 {
1346
-	if (Address < 0x4200)
1347
-	{
1348
-		/*switch (Address)
1349
-		{
1350
-			case 0x4016: // JOYSER0
1351
-				S9xSetJoypadLatch(Byte & 1);
1352
-				break;
1353
-
1354
-			case 0x4017: // JOYSER1
1355
-				return;
1356
-
1357
-			default:
1358
-				break;
1359
-		}*/
1360
-	}
1361
-	else
1362 646
 	if ((Address & 0xff80) == 0x4300)
1363 647
 	{
1364 648
 		if (CPU.InDMAorHDMA)
1365 649
 			return;
1366 650
 
1367
-		int	d = (Address >> 4) & 0x7;
651
+		int d = (Address >> 4) & 0x7;
1368 652
 
1369 653
 		switch (Address & 0xf)
1370 654
 		{
1371 655
 			case 0x0: // 0x43x0: DMAPx
1372
-				DMA[d].ReverseTransfer        = (Byte & 0x80) ? true : false;
1373
-				DMA[d].HDMAIndirectAddressing = (Byte & 0x40) ? true : false;
1374
-				DMA[d].UnusedBit43x0          = (Byte & 0x20) ? true : false;
1375
-				DMA[d].AAddressDecrement      = (Byte & 0x10) ? true : false;
1376
-				DMA[d].AAddressFixed          = (Byte & 0x08) ? true : false;
1377
-				DMA[d].TransferMode           = (Byte & 7);
656
+				DMA[d].ReverseTransfer = !!(Byte & 0x80);
657
+				DMA[d].HDMAIndirectAddressing = !!(Byte & 0x40);
658
+				DMA[d].UnusedBit43x0 = !!(Byte & 0x20);
659
+				DMA[d].AAddressDecrement = !!(Byte & 0x10);
660
+				DMA[d].AAddressFixed = !!(Byte & 0x08);
661
+				DMA[d].TransferMode = (Byte & 7);
1378 662
 				return;
1379 663
 
1380 664
 			case 0x1: // 0x43x1: BBADx
... ...
@@ -1393,36 +677,36 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1393 677
 
1394 678
 			case 0x4: // 0x43x4: A1Bx
1395 679
 				DMA[d].ABank = Byte;
1396
-				HDMAMemPointers[d] = NULL;
680
+				HDMAMemPointers[d] = nullptr;
1397 681
 				return;
1398 682
 
1399 683
 			case 0x5: // 0x43x5: DASxL
1400 684
 				DMA[d].DMACount_Or_HDMAIndirectAddress &= 0xff00;
1401 685
 				DMA[d].DMACount_Or_HDMAIndirectAddress |= Byte;
1402
-				HDMAMemPointers[d] = NULL;
686
+				HDMAMemPointers[d] = nullptr;
1403 687
 				return;
1404 688
 
1405 689
 			case 0x6: // 0x43x6: DASxH
1406 690
 				DMA[d].DMACount_Or_HDMAIndirectAddress &= 0xff;
1407 691
 				DMA[d].DMACount_Or_HDMAIndirectAddress |= Byte << 8;
1408
-				HDMAMemPointers[d] = NULL;
692
+				HDMAMemPointers[d] = nullptr;
1409 693
 				return;
1410 694
 
1411 695
 			case 0x7: // 0x43x7: DASBx
1412 696
 				DMA[d].IndirectBank = Byte;
1413
-				HDMAMemPointers[d] = NULL;
697
+				HDMAMemPointers[d] = nullptr;
1414 698
 				return;
1415 699
 
1416 700
 			case 0x8: // 0x43x8: A2AxL
1417 701
 				DMA[d].Address &= 0xff00;
1418 702
 				DMA[d].Address |= Byte;
1419
-				HDMAMemPointers[d] = NULL;
703
+				HDMAMemPointers[d] = nullptr;
1420 704
 				return;
1421 705
 
1422 706
 			case 0x9: // 0x43x9: A2AxH
1423 707
 				DMA[d].Address &= 0xff;
1424 708
 				DMA[d].Address |= Byte << 8;
1425
-				HDMAMemPointers[d] = NULL;
709
+				HDMAMemPointers[d] = nullptr;
1426 710
 				return;
1427 711
 
1428 712
 			case 0xa: // 0x43xa: NLTRx
... ...
@@ -1443,94 +727,57 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1443 727
 			case 0xf: // 0x43xf: mirror of 0x43xb
1444 728
 				DMA[d].UnknownByte = Byte;
1445 729
 				return;
1446
-
1447
-			default:
1448
-				break;
1449 730
 		}
1450 731
 	}
1451
-	else
732
+	else if (Address >= 0x4200)
1452 733
 	{
1453
-		uint16_t	pos;
734
+		uint16_t pos;
1454 735
 
1455 736
 		switch (Address)
1456 737
 		{
1457 738
 			case 0x4200: // NMITIMEN
1458
-				if (Byte & 0x20)
1459
-				{
1460
-					PPU.VTimerEnabled = true;
1461
-				#ifdef DEBUGGER
1462
-					missing.virq = 1;
1463
-					missing.virq_pos = PPU.IRQVBeamPos;
1464
-				#endif
1465
-				}
1466
-				else
1467
-					PPU.VTimerEnabled = false;
1468
-
1469
-				if (Byte & 0x10)
1470
-				{
1471
-					PPU.HTimerEnabled = true;
1472
-				#ifdef DEBUGGER
1473
-					missing.hirq = 1;
1474
-					missing.hirq_pos = PPU.IRQHBeamPos;
1475
-				#endif
1476
-				}
1477
-				else
1478
-					PPU.HTimerEnabled = false;
739
+				PPU.VTimerEnabled = !!(Byte & 0x20);
740
+				PPU.HTimerEnabled = !!(Byte & 0x10);
1479 741
 
1480 742
 				if (CPU.IRQLine && !PPU.HTimerEnabled && PPU.VTimerEnabled)
1481 743
 					CPU.IRQTransition = true;
1482 744
 
1483 745
 				if (!PPU.HTimerEnabled && !PPU.VTimerEnabled)
1484
-				{
1485
-					CPU.IRQLine = false;
1486
-					CPU.IRQTransition = false;
1487
-				}
746
+					CPU.IRQLine = CPU.IRQTransition = false;
1488 747
 
1489 748
 				// NMI can trigger immediately during VBlank as long as NMI_read ($4210) wasn't cleard.
1490
-				if ((Byte & 0x80) && !(Memory.FillRAM[0x4200] & 0x80) &&
1491
-					(CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) && (Memory.FillRAM[0x4210] & 0x80))
749
+				if ((Byte & 0x80) && !(Memory.FillRAM[0x4200] & 0x80) && CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && (Memory.FillRAM[0x4210] & 0x80))
1492 750
 				{
1493 751
 					// FIXME: triggered at HC+=6, checked just before the final CPU cycle,
1494 752
 					// then, when to call S9xOpcode_NMI()?
1495 753
 					CPU.NMILine = true;
1496
-					Timings.NMITriggerPos = CPU.Cycles + 6 + 6;
754
+					Timings.NMITriggerPos = CPU.Cycles + 12;
1497 755
 				}
1498 756
 
1499 757
 				break;
1500 758
 
1501 759
 			case 0x4201: // WRIO
1502
-				if ((Byte & 0x80) == 0 && (Memory.FillRAM[0x4213] & 0x80) == 0x80)
1503
-					S9xLatchCounters(1);
1504
-				else
1505
-					S9xTryGunLatch((Byte & 0x80) ? true : false);
1506 760
 				Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = Byte;
1507 761
 				break;
1508 762
 
1509
-			case 0x4202: // WRMPYA
1510
-				break;
1511
-
1512 763
 			case 0x4203: // WRMPYB
1513 764
 			{
1514 765
 				uint32_t res = Memory.FillRAM[0x4202] * Byte;
1515 766
 				// FIXME: The update occurs 8 machine cycles after $4203 is set.
1516
-				Memory.FillRAM[0x4216] = (uint8_t) res;
1517
-				Memory.FillRAM[0x4217] = (uint8_t) (res >> 8);
767
+				Memory.FillRAM[0x4216] = static_cast<uint8_t>(res);
768
+				Memory.FillRAM[0x4217] = static_cast<uint8_t>(res >> 8);
1518 769
 				break;
1519 770
 			}
1520 771
 
1521
-			case 0x4204: // WRDIVL
1522
-			case 0x4205: // WRDIVH
1523
-				break;
1524
-
1525 772
 			case 0x4206: // WRDIVB
1526 773
 			{
1527 774
 				uint16_t a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8);
1528 775
 				uint16_t div = Byte ? a / Byte : 0xffff;
1529 776
 				uint16_t rem = Byte ? a % Byte : a;
1530 777
 				// FIXME: The update occurs 16 machine cycles after $4206 is set.
1531
-				Memory.FillRAM[0x4214] = (uint8_t) div;
778
+				Memory.FillRAM[0x4214] = static_cast<uint8_t>(div);
1532 779
 				Memory.FillRAM[0x4215] = div >> 8;
1533
-				Memory.FillRAM[0x4216] = (uint8_t) rem;
780
+				Memory.FillRAM[0x4216] = static_cast<uint8_t>(rem);
1534 781
 				Memory.FillRAM[0x4217] = rem >> 8;
1535 782
 				break;
1536 783
 			}
... ...
@@ -1540,9 +787,6 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1540 787
 				PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff00) | Byte;
1541 788
 				if (PPU.IRQHBeamPos != pos)
1542 789
 					S9xUpdateHVTimerPosition();
1543
-			#ifdef DEBUGGER
1544
-				missing.hirq_pos = PPU.IRQHBeamPos;
1545
-			#endif
1546 790
 				break;
1547 791
 
1548 792
 			case 0x4208: // HTIMEH
... ...
@@ -1550,9 +794,6 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1550 794
 				PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff) | ((Byte & 1) << 8);
1551 795
 				if (PPU.IRQHBeamPos != pos)
1552 796
 					S9xUpdateHVTimerPosition();
1553
-			#ifdef DEBUGGER
1554
-				missing.hirq_pos = PPU.IRQHBeamPos;
1555
-			#endif
1556 797
 				break;
1557 798
 
1558 799
 			case 0x4209: // VTIMEL
... ...
@@ -1560,9 +801,6 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1560 801
 				PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff00) | Byte;
1561 802
 				if (PPU.IRQVBeamPos != pos)
1562 803
 					S9xUpdateHVTimerPosition();
1563
-			#ifdef DEBUGGER
1564
-				missing.virq_pos = PPU.IRQVBeamPos;
1565
-			#endif
1566 804
 				break;
1567 805
 
1568 806
 			case 0x420a: // VTIMEH
... ...
@@ -1570,9 +808,6 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1570 808
 				PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff) | ((Byte & 1) << 8);
1571 809
 				if (PPU.IRQVBeamPos != pos)
1572 810
 					S9xUpdateHVTimerPosition();
1573
-			#ifdef DEBUGGER
1574
-				missing.virq_pos = PPU.IRQVBeamPos;
1575
-			#endif
1576 811
 				break;
1577 812
 
1578 813
 			case 0x420b: // MDMAEN
... ...
@@ -1597,10 +832,6 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1597 832
 					S9xDoDMA(6);
1598 833
 				if (Byte & 0x80)
1599 834
 					S9xDoDMA(7);
1600
-			#ifdef DEBUGGER
1601
-				missing.dma_this_frame = Byte;
1602
-				missing.dma_channels = Byte;
1603
-			#endif
1604 835
 				break;
1605 836
 
1606 837
 			case 0x420c: // HDMAEN
... ...
@@ -1609,22 +840,13 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1609 840
 				Memory.FillRAM[0x420c] = Byte;
1610 841
 				// Yoshi's Island, Genjyu Ryodan, Mortal Kombat, Tales of Phantasia
1611 842
 				PPU.HDMA = Byte & ~PPU.HDMAEnded;
1612
-			#ifdef DEBUGGER
1613
-				missing.hdma_this_frame |= Byte;
1614
-				missing.hdma_channels |= Byte;
1615
-			#endif
1616 843
 				break;
1617 844
 
1618 845
 			case 0x420d: // MEMSEL
1619 846
 				if ((Byte & 1) != (Memory.FillRAM[0x420d] & 1))
1620 847
 				{
1621 848
 					if (Byte & 1)
1622
-					{
1623 849
 						CPU.FastROMSpeed = ONE_CYCLE;
1624
-					#ifdef DEBUGGER
1625
-						missing.fast_rom = 1;
1626
-					#endif
1627
-					}
1628 850
 					else
1629 851
 						CPU.FastROMSpeed = SLOW_ONE_CYCLE;
1630 852
 				}
... ...
@@ -1650,58 +872,30 @@ void S9xSetCPU (uint8_t Byte, uint16_t Address)
1650 872
 				return;
1651 873
 
1652 874
 			default:
1653
-				/*if (Settings.SPC7110 && Address >= 0x4800)
1654
-					S9xSetSPC7110(Byte, Address);
1655
-				else*/
1656 875
 				if (Settings.SDD1 && Address >= 0x4804 && Address <= 0x4807)
1657 876
 					S9xSetSDD1MemoryMap(Address - 0x4804, Byte & 7);
1658
-				break;
1659 877
 		}
1660 878
 	}
1661 879
 
1662 880
 	Memory.FillRAM[Address] = Byte;
1663 881
 }
1664 882
 
1665
-uint8_t S9xGetCPU (uint16_t Address)
883
+uint8_t S9xGetCPU(uint16_t Address)
1666 884
 {
1667 885
 	if (Address < 0x4200)
1668
-	{
1669
-	#ifdef SNES_JOY_READ_CALLBACKS
1670
-		extern bool pad_read;
1671
-		if (Address == 0x4016 || Address == 0x4017)
1672
-		{
1673
-			S9xOnSNESPadRead();
1674
-			pad_read = true;
1675
-		}
1676
-	#endif
1677
-
1678
-		/*switch (Address)
1679
-		{
1680
-			case 0x4016: // JOYSER0
1681
-			case 0x4017: // JOYSER1
1682
-				return S9xReadJOYSERn(Address);
1683
-
1684
-			default:*/
1685
-				return OpenBus;
1686
-		//}
1687
-	}
1688
-	else
1689
-	if ((Address & 0xff80) == 0x4300)
886
+		return OpenBus;
887
+	else if ((Address & 0xff80) == 0x4300)
1690 888
 	{
1691 889
 		if (CPU.InDMAorHDMA)
1692 890
 			return OpenBus;
1693 891
 
1694
-		int	d = (Address >> 4) & 0x7;
892
+		int d = (Address >> 4) & 0x7;
1695 893
 
1696 894
 		switch (Address & 0xf)
1697 895
 		{
1698 896
 			case 0x0: // 0x43x0: DMAPx
1699
-				return  (DMA[d].ReverseTransfer        ? 0x80 : 0) |
1700
-						(DMA[d].HDMAIndirectAddressing ? 0x40 : 0) |
1701
-						(DMA[d].UnusedBit43x0          ? 0x20 : 0) |
1702
-						(DMA[d].AAddressDecrement      ? 0x10 : 0) |
1703
-						(DMA[d].AAddressFixed          ? 0x08 : 0) |
1704
-						(DMA[d].TransferMode & 7);
897
+				return (DMA[d].ReverseTransfer ? 0x80 : 0) | (DMA[d].HDMAIndirectAddressing ? 0x40 : 0) | (DMA[d].UnusedBit43x0 ? 0x20 : 0) | (DMA[d].AAddressDecrement ? 0x10 : 0) |
898
+					(DMA[d].AAddressFixed ? 0x08 : 0) | (DMA[d].TransferMode & 7);
1705 899
 
1706 900
 			case 0x1: // 0x43x1: BBADx
1707 901
 				return DMA[d].BAddress;
... ...
@@ -1743,7 +937,7 @@ uint8_t S9xGetCPU (uint16_t Address)
1743 937
 	}
1744 938
 	else
1745 939
 	{
1746
-		uint8_t	byte;
940
+		uint8_t byte;
1747 941
 
1748 942
 		switch (Address)
1749 943
 		{
... ...
@@ -1778,19 +972,9 @@ uint8_t S9xGetCPU (uint16_t Address)
1778 972
 			case 0x421d: // JOY3H
1779 973
 			case 0x421e: // JOY4L
1780 974
 			case 0x421f: // JOY4H
1781
-			#ifdef SNES_JOY_READ_CALLBACKS
1782
-				extern bool pad_read;
1783
-				if (Memory.FillRAM[0x4200] & 1)
1784
-				{
1785
-					S9xOnSNESPadRead();
1786
-					pad_read = true;
1787
-				}
1788
-			#endif
1789 975
 				return Memory.FillRAM[Address];
1790 976
 
1791 977
 			default:
1792
-				/*if (Settings.SPC7110 && Address >= 0x4800)
1793
-					return S9xGetSPC7110(Address);*/
1794 978
 				if (Settings.SDD1 && Address >= 0x4800 && Address <= 0x4807)
1795 979
 					return Memory.FillRAM[Address];
1796 980
 				return OpenBus;
... ...
@@ -1801,186 +985,65 @@ uint8_t S9xGetCPU (uint16_t Address)
1801 985
 void S9xResetPPU()
1802 986
 {
1803 987
 	S9xSoftResetPPU();
1804
-	//S9xControlsReset();
1805
-	PPU.M7HOFS = 0;
1806
-	PPU.M7VOFS = 0;
1807 988
 	PPU.M7byte = 0;
1808 989
 }
1809 990
 
1810 991
 void S9xSoftResetPPU()
1811 992
 {
1812
-	//S9xControlsSoftReset();
1813
-
1814
-	PPU.VMA.High = 0;
993
+	PPU.VMA.High = false;
1815 994
 	PPU.VMA.Increment = 1;
1816
-	PPU.VMA.Address = 0;
1817
-	PPU.VMA.FullGraphicCount = 0;
1818
-	PPU.VMA.Shift = 0;
995
+	PPU.VMA.Address = PPU.VMA.FullGraphicCount = PPU.VMA.Shift = 0;
1819 996
 
1820 997
 	PPU.WRAM = 0;
1821 998
 
1822
-	for (int c = 0; c < 4; c++)
1823
-	{
1824
-		PPU.BG[c].SCBase = 0;
1825
-		PPU.BG[c].HOffset = 0;
1826
-		PPU.BG[c].VOffset = 0;
1827
-		PPU.BG[c].BGSize = 0;
1828
-		PPU.BG[c].NameBase = 0;
1829
-		PPU.BG[c].SCSize = 0;
1830
-	}
1831
-
1832
-	PPU.BGMode = 0;
1833
-	PPU.BG3Priority = 0;
1834
-
1835
-	PPU.CGFLIP = 0;
1836
-	PPU.CGFLIPRead = 0;
999
+	PPU.CGFLIPRead = false;
1837 1000
 	PPU.CGADD = 0;
1838 1001
 
1839
-	for (int c = 0; c < 256; c++)
1002
+	for (int c = 0; c < 256; ++c)
1840 1003
 	{
1841
-		IPPU.Red[c]   = (c & 7) << 2;
1004
+		IPPU.Red[c] = (c & 7) << 2;
1842 1005
 		IPPU.Green[c] = ((c >> 3) & 7) << 2;
1843
-		IPPU.Blue[c]  = ((c >> 6) & 2) << 3;
1006
+		IPPU.Blue[c] = ((c >> 6) & 2) << 3;
1844 1007
 		PPU.CGDATA[c] = IPPU.Red[c] | (IPPU.Green[c] << 5) | (IPPU.Blue[c] << 10);
1845 1008
 	}
1846 1009
 
1847
-	for (int c = 0; c < 128; c++)
1848
-	{
1849
-		PPU.OBJ[c].HPos = 0;
1850
-		PPU.OBJ[c].VPos = 0;
1851
-		PPU.OBJ[c].HFlip = 0;
1852
-		PPU.OBJ[c].VFlip = 0;
1853
-		PPU.OBJ[c].Name = 0;
1854
-		PPU.OBJ[c].Priority = 0;
1855
-		PPU.OBJ[c].Palette = 0;
1856
-		PPU.OBJ[c].Size = 0;
1857
-	}
1858
-
1859
-	PPU.OBJThroughMain = false;
1860
-	PPU.OBJThroughSub = false;
1861
-	PPU.OBJAddition = false;
1862
-	PPU.OBJNameBase = 0;
1863
-	PPU.OBJNameSelect = 0;
1864
-	PPU.OBJSizeSelect = 0;
1865
-
1866
-	PPU.OAMAddr = 0;
1867
-	PPU.SavedOAMAddr = 0;
1868
-	PPU.OAMPriorityRotation = 0;
1010
+	PPU.OAMAddr = PPU.SavedOAMAddr = 0;
1011
+	PPU.OAMPriorityRotation = false;
1869 1012
 	PPU.OAMFlip = 0;
1870
-	PPU.OAMReadFlip = 0;
1871
-	PPU.OAMTileAddress = 0;
1872 1013
 	PPU.OAMWriteRegister = 0;
1873
-	ZeroMemory(PPU.OAMData, 512 + 32);
1014
+	std::fill(&PPU.OAMData[0], &PPU.OAMData[512 + 32], 0);
1874 1015
 
1875 1016
 	PPU.FirstSprite = 0;
1876
-	PPU.LastSprite = 127;
1877
-	PPU.RangeTimeOver = 0;
1878 1017
 
1879
-	PPU.HTimerEnabled = false;
1880
-	PPU.VTimerEnabled = false;
1018
+	PPU.HTimerEnabled = PPU.VTimerEnabled = false;
1881 1019
 	PPU.HTimerPosition = Timings.H_Max + 1;
1882 1020
 	PPU.VTimerPosition = Timings.V_Max + 1;
1883
-	PPU.IRQHBeamPos = 0x1ff;
1884
-	PPU.IRQVBeamPos = 0x1ff;
1885
-
1886
-	PPU.HBeamFlip = 0;
1887
-	PPU.VBeamFlip = 0;
1888
-	PPU.HBeamPosLatched = 0;
1889
-	PPU.VBeamPosLatched = 0;
1890
-	PPU.GunHLatch = 0;
1891
-	PPU.GunVLatch = 1000;
1892
-	PPU.HVBeamCounterLatched = 0;
1893
-
1894
-	PPU.Mode7HFlip = false;
1895
-	PPU.Mode7VFlip = false;
1896
-	PPU.Mode7Repeat = 0;
1897
-	PPU.MatrixA = 0;
1898
-	PPU.MatrixB = 0;
1899
-	PPU.MatrixC = 0;
1900
-	PPU.MatrixD = 0;
1901
-	PPU.CentreX = 0;
1902
-	PPU.CentreY = 0;
1903
-
1904
-	PPU.Mosaic = 0;
1905
-	PPU.BGMosaic[0] = false;
1906
-	PPU.BGMosaic[1] = false;
1907
-	PPU.BGMosaic[2] = false;
1908
-	PPU.BGMosaic[3] = false;
1909
-	
1910
-	PPU.Window1Left = 1;
1911
-	PPU.Window1Right = 0;
1912
-	PPU.Window2Left = 1;
1913
-	PPU.Window2Right = 0;
1914
-	PPU.RecomputeClipWindows = true;
1915
-
1916
-	for (int c = 0; c < 6; c++)
1917
-	{
1918
-		PPU.ClipCounts[c] = 0;
1919
-		PPU.ClipWindowOverlapLogic[c] = CLIP_OR;
1920
-		PPU.ClipWindow1Enable[c] = false;
1921
-		PPU.ClipWindow2Enable[c] = false;
1922
-		PPU.ClipWindow1Inside[c] = true;
1923
-		PPU.ClipWindow2Inside[c] = true;
1924
-	}
1021
+	PPU.IRQHBeamPos = PPU.IRQVBeamPos = 0x1ff;
1022
+
1023
+	PPU.HBeamFlip = PPU.VBeamFlip = false;
1024
+
1025
+	PPU.MatrixA = PPU.MatrixB = 0;
1925 1026
 
1926 1027
 	PPU.ForcedBlanking = true;
1927 1028
 
1928
-	PPU.FixedColourRed = 0;
1929
-	PPU.FixedColourGreen = 0;
1930
-	PPU.FixedColourBlue = 0;
1931
-	PPU.Brightness = 0;
1932 1029
 	PPU.ScreenHeight = SNES_HEIGHT;
1933 1030
 
1934 1031
 	PPU.Need16x8Mulitply = false;
1935
-	PPU.BGnxOFSbyte = 0;
1936
-
1937
-	PPU.HDMA = 0;
1938
-	PPU.HDMAEnded = 0;
1939
-
1940
-	PPU.OpenBus1 = 0;
1941
-	PPU.OpenBus2 = 0;
1942
-
1943
-	for (int c = 0; c < 2; c++)
1944
-		memset(&IPPU.Clip[c], 0, sizeof(struct ClipData));
1945
-	IPPU.ColorsChanged = true;
1946
-	IPPU.OBJChanged = true;
1947
-	IPPU.DirectColourMapsNeedRebuild = true;
1948
-	ZeroMemory(IPPU.TileCached[TILE_2BIT], MAX_2BIT_TILES);
1949
-	ZeroMemory(IPPU.TileCached[TILE_4BIT], MAX_4BIT_TILES);
1950
-	ZeroMemory(IPPU.TileCached[TILE_8BIT], MAX_8BIT_TILES);
1951
-	ZeroMemory(IPPU.TileCached[TILE_2BIT_EVEN], MAX_2BIT_TILES);
1952
-	ZeroMemory(IPPU.TileCached[TILE_2BIT_ODD],  MAX_2BIT_TILES);
1953
-	ZeroMemory(IPPU.TileCached[TILE_4BIT_EVEN], MAX_4BIT_TILES);
1954
-	ZeroMemory(IPPU.TileCached[TILE_4BIT_ODD],  MAX_4BIT_TILES);
1032
+
1033
+	PPU.HDMA = PPU.HDMAEnded = 0;
1034
+
1035
+	PPU.OpenBus1 = PPU.OpenBus2 = 0;
1036
+
1955 1037
 	IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better?
1956 1038
 	IPPU.Interlace = false;
1957
-	IPPU.InterlaceOBJ = false;
1958
-	IPPU.DoubleWidthPixels = false;
1959
-	IPPU.DoubleHeightPixels = false;
1960
-	IPPU.CurrentLine = 0;
1961
-	IPPU.PreviousLine = 0;
1962
-	IPPU.XB = NULL;
1963
-	for (int c = 0; c < 256; c++)
1964
-		IPPU.ScreenColors[c] = c;
1965
-	IPPU.MaxBrightness = 0;
1966
-	IPPU.RenderThisFrame = true;
1967
-	IPPU.RenderedScreenWidth = SNES_WIDTH;
1968
-	IPPU.RenderedScreenHeight = SNES_HEIGHT;
1969
-	IPPU.FrameCount = 0;
1970
-	IPPU.RenderedFramesCount = 0;
1971
-	IPPU.DisplayedRenderedFrameCount = 0;
1972
-	IPPU.SkippedFrames = 0;
1973
-	IPPU.FrameSkip = 0;
1974
-
1975
-	//S9xFixColourBrightness();
1976 1039
 
1977 1040
 	for (int c = 0; c < 0x8000; c += 0x100)
1978
-		memset(&Memory.FillRAM[c], c >> 8, 0x100);
1979
-	ZeroMemory(&Memory.FillRAM[0x2100], 0x100);
1980
-	ZeroMemory(&Memory.FillRAM[0x4200], 0x100);
1981
-	ZeroMemory(&Memory.FillRAM[0x4000], 0x100);
1041
+		std::fill(&Memory.FillRAM[c], &Memory.FillRAM[c + 0x100], c >> 8);
1042
+	std::fill(&Memory.FillRAM[0x2100], &Memory.FillRAM[0x2200], 0);
1043
+	std::fill(&Memory.FillRAM[0x4200], &Memory.FillRAM[0x4300], 0);
1044
+	std::fill(&Memory.FillRAM[0x4000], &Memory.FillRAM[0x4100], 0);
1982 1045
 	// For BS Suttehakkun 2...
1983
-	ZeroMemory(&Memory.FillRAM[0x1000], 0x1000);
1046
+	std::fill(&Memory.FillRAM[0x1000], &Memory.FillRAM[0x2000], 0);
1984 1047
 
1985 1048
 	Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = 0xff;
1986 1049
 }
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,1986 @@
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 "dma.h"
181
+#include "apu/apu.h"
182
+//#include "fxemu.h"
183
+#include "sdd1.h"
184
+//#include "srtc.h"
185
+//#include "controls.h"
186
+//#include "movie.h"
187
+//#include "display.h"
188
+#ifdef NETPLAY_SUPPORT
189
+#include "netplay.h"
190
+#endif
191
+#ifdef DEBUGGER
192
+#include "debug.h"
193
+#include "missing.h"
194
+#endif
195
+
196
+extern uint8_t	*HDMAMemPointers[8];
197
+
198
+static inline void S9xLatchCounters (bool force)
199
+{
200
+	if (force || (Memory.FillRAM[0x4213] & 0x80))
201
+	{
202
+		// Latch h and v counters, like the gun
203
+	#ifdef DEBUGGER
204
+		missing.h_v_latch = 1;
205
+	#endif
206
+
207
+		PPU.HVBeamCounterLatched = 1;
208
+		PPU.VBeamPosLatched = (uint16_t) CPU.V_Counter;
209
+
210
+		// From byuu:
211
+		// All dots are 4 cycles long, except dots 322 and 326. dots 322 and 326 are 6 cycles long.
212
+		// This holds true for all scanlines except scanline 240 on non-interlace odd frames.
213
+		// The reason for this is because this scanline is only 1360 cycles long,
214
+		// instead of 1364 like all other scanlines.
215
+		// This makes the effective range of hscan_pos 0-339 at all times.
216
+		int32_t	hc = CPU.Cycles;
217
+
218
+		if (Timings.H_Max == Timings.H_Max_Master) // 1364
219
+		{
220
+			if (hc >= 1292)
221
+				hc -= (ONE_DOT_CYCLE / 2);
222
+			if (hc >= 1308)
223
+				hc -= (ONE_DOT_CYCLE / 2);
224
+		}
225
+
226
+		PPU.HBeamPosLatched = (uint16_t) (hc / ONE_DOT_CYCLE);
227
+
228
+		Memory.FillRAM[0x213f] |= 0x40;
229
+	}
230
+
231
+	if (CPU.V_Counter >  PPU.GunVLatch || (CPU.V_Counter == PPU.GunVLatch && CPU.Cycles >= PPU.GunHLatch * ONE_DOT_CYCLE))
232
+		PPU.GunVLatch = 1000;
233
+}
234
+
235
+static inline void S9xTryGunLatch (bool force)
236
+{
237
+	if (CPU.V_Counter >  PPU.GunVLatch || (CPU.V_Counter == PPU.GunVLatch && CPU.Cycles >= PPU.GunHLatch * ONE_DOT_CYCLE))
238
+	{
239
+		if (force || (Memory.FillRAM[0x4213] & 0x80))
240
+		{
241
+		#ifdef DEBUGGER
242
+			missing.h_v_latch = 1;
243
+		#endif
244
+
245
+			PPU.HVBeamCounterLatched = 1;
246
+			PPU.VBeamPosLatched = (uint16_t) PPU.GunVLatch;
247
+			PPU.HBeamPosLatched = (uint16_t) PPU.GunHLatch;
248
+
249
+			Memory.FillRAM[0x213f] |= 0x40;
250
+		}
251
+
252
+		PPU.GunVLatch = 1000;
253
+	}
254
+}
255
+
256
+void S9xUpdateHVTimerPosition()
257
+{
258
+	PPU.HTimerPosition = PPU.IRQHBeamPos * ONE_DOT_CYCLE + Timings.IRQTriggerCycles;
259
+	if (Timings.H_Max == Timings.H_Max_Master)	// 1364
260
+	{
261
+		if (PPU.IRQHBeamPos > 322)
262
+			PPU.HTimerPosition += (ONE_DOT_CYCLE / 2);
263
+		if (PPU.IRQHBeamPos > 326)
264
+			PPU.HTimerPosition += (ONE_DOT_CYCLE / 2);
265
+	}
266
+
267
+	PPU.VTimerPosition = PPU.IRQVBeamPos;
268
+
269
+	if ((PPU.HTimerPosition >= Timings.H_Max) && (PPU.IRQHBeamPos < 340))
270
+	{
271
+		PPU.HTimerPosition -= Timings.H_Max;
272
+		PPU.VTimerPosition++;
273
+		// FIXME
274
+		if (PPU.VTimerPosition >= Timings.V_Max)
275
+			PPU.VTimerPosition = 0;
276
+	}
277
+
278
+#ifdef DEBUGGER
279
+	S9xTraceFormattedMessage("--- IRQ Timer set  HTimer:%d Pos:%04d  VTimer:%d Pos:%03d",
280
+		PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition);
281
+#endif
282
+}
283
+
284
+/*void S9xFixColourBrightness()
285
+{
286
+	IPPU.XB = mul_brightness[PPU.Brightness];
287
+
288
+	for (int i = 0; i < 256; i++)
289
+	{
290
+		IPPU.Red[i]   = IPPU.XB[(PPU.CGDATA[i])       & 0x1f];
291
+		IPPU.Green[i] = IPPU.XB[(PPU.CGDATA[i] >>  5) & 0x1f];
292
+		IPPU.Blue[i]  = IPPU.XB[(PPU.CGDATA[i] >> 10) & 0x1f];
293
+		IPPU.ScreenColors[i] = BUILD_PIXEL(IPPU.Red[i], IPPU.Green[i], IPPU.Blue[i]);
294
+	}
295
+}*/
296
+
297
+void S9xSetPPU (uint8_t Byte, uint16_t Address)
298
+{
299
+	// MAP_PPU: $2000-$3FFF
300
+
301
+	if (CPU.InDMAorHDMA)
302
+	{
303
+		if (CPU.CurrentDMAorHDMAChannel >= 0 && DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer)
304
+		{
305
+			// S9xSetPPU() is called to write to DMA[].AAddress
306
+			if ((Address & 0xff00) == 0x2100)
307
+			{
308
+				// Cannot access to Address Bus B ($2100-$21ff) via (H)DMA
309
+				return;
310
+			}
311
+			else
312
+			{
313
+				// 0x2000-0x3FFF is connected to Address Bus A
314
+				// SA1, SuperFX and SRTC are mapped here
315
+				// I don't bother for now...
316
+				return;
317
+			}
318
+		}
319
+		else
320
+		{
321
+			// S9xSetPPU() is called to read from $21xx
322
+			// Take care of DMA wrapping
323
+			if (Address > 0x21ff)
324
+				Address = 0x2100 + (Address & 0xff);
325
+		}
326
+	}
327
+
328
+#ifdef DEBUGGER
329
+	if (CPU.InHDMA)
330
+		S9xTraceFormattedMessage("--- HDMA PPU %04X -> %02X", Address, Byte);
331
+#endif
332
+
333
+	if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3
334
+		// write_port will run the APU until given clock before writing value
335
+		S9xAPUWritePort(Address & 3, Byte);
336
+	else
337
+	if (Address <= 0x2183)
338
+	{
339
+		switch (Address)
340
+		{
341
+			case 0x2100: // INIDISP
342
+				if (Byte != Memory.FillRAM[0x2100])
343
+				{
344
+					//FLUSH_REDRAW();
345
+
346
+					if (PPU.Brightness != (Byte & 0xf))
347
+					{
348
+						IPPU.ColorsChanged = true;
349
+						IPPU.DirectColourMapsNeedRebuild = true;
350
+						PPU.Brightness = Byte & 0xf;
351
+						//S9xFixColourBrightness();
352
+						if (PPU.Brightness > IPPU.MaxBrightness)
353
+							IPPU.MaxBrightness = PPU.Brightness;
354
+					}
355
+
356
+					if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80))
357
+					{
358
+						IPPU.ColorsChanged = true;
359
+						PPU.ForcedBlanking = (Byte >> 7) & 1;
360
+					}
361
+				}
362
+
363
+				if ((Memory.FillRAM[0x2100] & 0x80) && CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)
364
+				{
365
+					PPU.OAMAddr = PPU.SavedOAMAddr;
366
+
367
+					uint8_t tmp = 0;
368
+					if (PPU.OAMPriorityRotation)
369
+						tmp = (PPU.OAMAddr & 0xfe) >> 1;
370
+					if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
371
+					{
372
+						PPU.FirstSprite = tmp;
373
+						IPPU.OBJChanged = true;
374
+					}
375
+
376
+					PPU.OAMFlip = 0;
377
+				}
378
+
379
+				break;
380
+
381
+			case 0x2101: // OBSEL
382
+				if (Byte != Memory.FillRAM[0x2101])
383
+				{
384
+					//FLUSH_REDRAW();
385
+					PPU.OBJNameBase = (Byte & 3) << 14;
386
+					PPU.OBJNameSelect = ((Byte >> 3) & 3) << 13;
387
+					PPU.OBJSizeSelect = (Byte >> 5) & 7;
388
+					IPPU.OBJChanged = true;
389
+				}
390
+
391
+				break;
392
+
393
+			case 0x2102: // OAMADDL
394
+				PPU.OAMAddr = ((Memory.FillRAM[0x2103] & 1) << 8) | Byte;
395
+				PPU.OAMFlip = 2;
396
+				PPU.OAMReadFlip = 0;
397
+				PPU.SavedOAMAddr = PPU.OAMAddr;
398
+				if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
399
+				{
400
+					PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1;
401
+					IPPU.OBJChanged = true;
402
+				#ifdef DEBUGGER
403
+					missing.sprite_priority_rotation = 1;
404
+				#endif
405
+				}
406
+
407
+				break;
408
+
409
+			case 0x2103: // OAMADDH
410
+				PPU.OAMAddr = ((Byte & 1) << 8) | Memory.FillRAM[0x2102];
411
+				PPU.OAMPriorityRotation = (Byte & 0x80) ? 1 : 0;
412
+				if (PPU.OAMPriorityRotation)
413
+				{
414
+					if (PPU.FirstSprite != (PPU.OAMAddr >> 1))
415
+					{
416
+						PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1;
417
+						IPPU.OBJChanged = true;
418
+					#ifdef DEBUGGER
419
+						missing.sprite_priority_rotation = 1;
420
+					#endif
421
+					}
422
+				}
423
+				else
424
+				{
425
+					if (PPU.FirstSprite != 0)
426
+					{
427
+						PPU.FirstSprite = 0;
428
+						IPPU.OBJChanged = true;
429
+					#ifdef DEBUGGER
430
+						missing.sprite_priority_rotation = 1;
431
+					#endif
432
+					}
433
+				}
434
+
435
+				PPU.OAMFlip = 0;
436
+				PPU.OAMReadFlip = 0;
437
+				PPU.SavedOAMAddr = PPU.OAMAddr;
438
+
439
+				break;
440
+
441
+			case 0x2104: // OAMDATA
442
+				REGISTER_2104(Byte);
443
+				break;
444
+
445
+			case 0x2105: // BGMODE
446
+				if (Byte != Memory.FillRAM[0x2105])
447
+				{
448
+					//FLUSH_REDRAW();
449
+					PPU.BG[0].BGSize = (Byte >> 4) & 1;
450
+					PPU.BG[1].BGSize = (Byte >> 5) & 1;
451
+					PPU.BG[2].BGSize = (Byte >> 6) & 1;
452
+					PPU.BG[3].BGSize = (Byte >> 7) & 1;
453
+					PPU.BGMode = Byte & 7;
454
+					// BJ: BG3Priority only takes effect if BGMode == 1 and the bit is set
455
+					PPU.BG3Priority = ((Byte & 0x0f) == 0x09);
456
+					IPPU.Interlace = Memory.FillRAM[0x2133] & 1;
457
+				#ifdef DEBUGGER
458
+					missing.modes[PPU.BGMode] = 1;
459
+				#endif
460
+				}
461
+
462
+				break;
463
+
464
+			case 0x2106: // MOSAIC
465
+				if (Byte != Memory.FillRAM[0x2106])
466
+				{
467
+					//FLUSH_REDRAW();
468
+					PPU.MosaicStart = CPU.V_Counter;
469
+					if (PPU.MosaicStart > PPU.ScreenHeight)
470
+						PPU.MosaicStart = 0;
471
+					PPU.Mosaic = (Byte >> 4) + 1;
472
+					PPU.BGMosaic[0] = (Byte & 1);
473
+					PPU.BGMosaic[1] = !!(Byte & 2);
474
+					PPU.BGMosaic[2] = !!(Byte & 4);
475
+					PPU.BGMosaic[3] = !!(Byte & 8);
476
+				#ifdef DEBUGGER
477
+					if ((Byte & 0xf0) && (Byte & 0x0f))
478
+						missing.mosaic = 1;
479
+				#endif
480
+				}
481
+
482
+				break;
483
+
484
+			case 0x2107: // BG1SC
485
+				if (Byte != Memory.FillRAM[0x2107])
486
+				{
487
+					//FLUSH_REDRAW();
488
+					PPU.BG[0].SCSize = Byte & 3;
489
+					PPU.BG[0].SCBase = (Byte & 0x7c) << 8;
490
+				}
491
+
492
+				break;
493
+
494
+			case 0x2108: // BG2SC
495
+				if (Byte != Memory.FillRAM[0x2108])
496
+				{
497
+					//FLUSH_REDRAW();
498
+					PPU.BG[1].SCSize = Byte & 3;
499
+					PPU.BG[1].SCBase = (Byte & 0x7c) << 8;
500
+				}
501
+
502
+				break;
503
+
504
+			case 0x2109: // BG3SC
505
+				if (Byte != Memory.FillRAM[0x2109])
506
+				{
507
+					//FLUSH_REDRAW();
508
+					PPU.BG[2].SCSize = Byte & 3;
509
+					PPU.BG[2].SCBase = (Byte & 0x7c) << 8;
510
+				}
511
+
512
+				break;
513
+
514
+			case 0x210a: // BG4SC
515
+				if (Byte != Memory.FillRAM[0x210a])
516
+				{
517
+					//FLUSH_REDRAW();
518
+					PPU.BG[3].SCSize = Byte & 3;
519
+					PPU.BG[3].SCBase = (Byte & 0x7c) << 8;
520
+				}
521
+
522
+				break;
523
+
524
+			case 0x210b: // BG12NBA
525
+				if (Byte != Memory.FillRAM[0x210b])
526
+				{
527
+					//FLUSH_REDRAW();
528
+					PPU.BG[0].NameBase = (Byte & 7) << 12;
529
+					PPU.BG[1].NameBase = ((Byte >> 4) & 7) << 12;
530
+				}
531
+
532
+				break;
533
+
534
+			case 0x210c: // BG34NBA
535
+				if (Byte != Memory.FillRAM[0x210c])
536
+				{
537
+					//FLUSH_REDRAW();
538
+					PPU.BG[2].NameBase = (Byte & 7) << 12;
539
+					PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12;
540
+				}
541
+
542
+				break;
543
+
544
+			case 0x210d: // BG1HOFS, M7HOFS
545
+				PPU.BG[0].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[0].HOffset >> 8) & 7);
546
+				PPU.M7HOFS = (Byte << 8) | PPU.M7byte;
547
+				PPU.BGnxOFSbyte = Byte;
548
+				PPU.M7byte = Byte;
549
+				break;
550
+
551
+			case 0x210e: // BG1VOFS, M7VOFS
552
+				PPU.BG[0].VOffset = (Byte << 8) | PPU.BGnxOFSbyte;
553
+				PPU.M7VOFS = (Byte << 8) | PPU.M7byte;
554
+				PPU.BGnxOFSbyte = Byte;
555
+				PPU.M7byte = Byte;
556
+				break;
557
+
558
+			case 0x210f: // BG2HOFS
559
+				PPU.BG[1].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[1].HOffset >> 8) & 7);
560
+				PPU.BGnxOFSbyte = Byte;
561
+				break;
562
+
563
+			case 0x2110: // BG2VOFS
564
+				PPU.BG[1].VOffset = (Byte << 8) | PPU.BGnxOFSbyte;
565
+				PPU.BGnxOFSbyte = Byte;
566
+				break;
567
+
568
+			case 0x2111: // BG3HOFS
569
+				PPU.BG[2].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[2].HOffset >> 8) & 7);
570
+				PPU.BGnxOFSbyte = Byte;
571
+				break;
572
+
573
+			case 0x2112: // BG3VOFS
574
+				PPU.BG[2].VOffset = (Byte << 8) | PPU.BGnxOFSbyte;
575
+				PPU.BGnxOFSbyte = Byte;
576
+				break;
577
+
578
+			case 0x2113: // BG4HOFS
579
+				PPU.BG[3].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[3].HOffset >> 8) & 7);
580
+				PPU.BGnxOFSbyte = Byte;
581
+				break;
582
+
583
+			case 0x2114: // BG4VOFS
584
+				PPU.BG[3].VOffset = (Byte << 8) | PPU.BGnxOFSbyte;
585
+				PPU.BGnxOFSbyte = Byte;
586
+				break;
587
+
588
+			case 0x2115: // VMAIN
589
+				PPU.VMA.High = (Byte & 0x80) == 0 ? false : true;
590
+				switch (Byte & 3)
591
+				{
592
+					case 0: PPU.VMA.Increment = 1;   break;
593
+					case 1: PPU.VMA.Increment = 32;  break;
594
+					case 2: PPU.VMA.Increment = 128; break;
595
+					case 3: PPU.VMA.Increment = 128; break;
596
+				}
597
+
598
+				if (Byte & 0x0c)
599
+				{
600
+					static uint16_t Shift[4]    = { 0, 5, 6, 7 };
601
+					static uint16_t IncCount[4] = { 0, 32, 64, 128 };
602
+
603
+					uint8_t i = (Byte & 0x0c) >> 2;
604
+					PPU.VMA.FullGraphicCount = IncCount[i];
605
+					PPU.VMA.Mask1 = IncCount[i] * 8 - 1;
606
+					PPU.VMA.Shift = Shift[i];
607
+				#ifdef DEBUGGER
608
+					missing.vram_full_graphic_inc = (Byte & 0x0c) >> 2;
609
+				#endif
610
+				}
611
+				else
612
+					PPU.VMA.FullGraphicCount = 0;
613
+			#ifdef DEBUGGER
614
+				if (Byte & 3)
615
+					missing.vram_inc = Byte & 3;
616
+			#endif
617
+				break;
618
+
619
+			case 0x2116: // VMADDL
620
+				PPU.VMA.Address &= 0xff00;
621
+				PPU.VMA.Address |= Byte;
622
+
623
+				if (PPU.VMA.FullGraphicCount)
624
+				{
625
+					uint32_t addr = PPU.VMA.Address;
626
+					uint32_t rem = addr & PPU.VMA.Mask1;
627
+					uint32_t address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
628
+					IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff));
629
+				}
630
+				else
631
+					IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
632
+
633
+				break;
634
+
635
+			case 0x2117: // VMADDH
636
+				PPU.VMA.Address &= 0x00ff;
637
+				PPU.VMA.Address |= Byte << 8;
638
+
639
+				if (PPU.VMA.FullGraphicCount)
640
+				{
641
+					uint32_t addr = PPU.VMA.Address;
642
+					uint32_t rem = addr & PPU.VMA.Mask1;
643
+					uint32_t address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
644
+					IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff));
645
+				}
646
+				else
647
+					IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
648
+
649
+				break;
650
+
651
+			case 0x2118: // VMDATAL
652
+				REGISTER_2118(Byte);
653
+				break;
654
+
655
+			case 0x2119: // VMDATAH
656
+				REGISTER_2119(Byte);
657
+				break;
658
+
659
+			case 0x211a: // M7SEL
660
+				if (Byte != Memory.FillRAM[0x211a])
661
+				{
662
+					//FLUSH_REDRAW();
663
+					PPU.Mode7Repeat = Byte >> 6;
664
+					if (PPU.Mode7Repeat == 1)
665
+						PPU.Mode7Repeat = 0;
666
+					PPU.Mode7VFlip = !!((Byte & 2) >> 1);
667
+					PPU.Mode7HFlip = Byte & 1;
668
+				}
669
+
670
+				break;
671
+
672
+			case 0x211b: // M7A
673
+				PPU.MatrixA = PPU.M7byte | (Byte << 8);
674
+				PPU.Need16x8Mulitply = true;
675
+				PPU.M7byte = Byte;
676
+				break;
677
+
678
+			case 0x211c: // M7B
679
+				PPU.MatrixB = PPU.M7byte | (Byte << 8);
680
+				PPU.Need16x8Mulitply = true;
681
+				PPU.M7byte = Byte;
682
+				break;
683
+
684
+			case 0x211d: // M7C
685
+				PPU.MatrixC = PPU.M7byte | (Byte << 8);
686
+				PPU.M7byte = Byte;
687
+				break;
688
+
689
+			case 0x211e: // M7D
690
+				PPU.MatrixD = PPU.M7byte | (Byte << 8);
691
+				PPU.M7byte = Byte;
692
+				break;
693
+
694
+			case 0x211f: // M7X
695
+				PPU.CentreX = PPU.M7byte | (Byte << 8);
696
+				PPU.M7byte = Byte;
697
+				break;
698
+
699
+			case 0x2120: // M7Y
700
+				PPU.CentreY = PPU.M7byte | (Byte << 8);
701
+				PPU.M7byte = Byte;
702
+				break;
703
+
704
+			case 0x2121: // CGADD
705
+				PPU.CGFLIP = 0;
706
+				PPU.CGFLIPRead = 0;
707
+				PPU.CGADD = Byte;
708
+				break;
709
+
710
+			/*case 0x2122: // CGDATA
711
+				REGISTER_2122(Byte);
712
+				break;*/
713
+
714
+			case 0x2123: // W12SEL
715
+				if (Byte != Memory.FillRAM[0x2123])
716
+				{
717
+					//FLUSH_REDRAW();
718
+					PPU.ClipWindow1Enable[0] = !!(Byte & 0x02);
719
+					PPU.ClipWindow1Enable[1] = !!(Byte & 0x20);
720
+					PPU.ClipWindow2Enable[0] = !!(Byte & 0x08);
721
+					PPU.ClipWindow2Enable[1] = !!(Byte & 0x80);
722
+					PPU.ClipWindow1Inside[0] = !(Byte & 0x01);
723
+					PPU.ClipWindow1Inside[1] = !(Byte & 0x10);
724
+					PPU.ClipWindow2Inside[0] = !(Byte & 0x04);
725
+					PPU.ClipWindow2Inside[1] = !(Byte & 0x40);
726
+					PPU.RecomputeClipWindows = true;
727
+				#ifdef DEBUGGER
728
+					if (Byte & 0x80)
729
+						missing.window2[1] = 1;
730
+					if (Byte & 0x20)
731
+						missing.window1[1] = 1;
732
+					if (Byte & 0x08)
733
+						missing.window2[0] = 1;
734
+					if (Byte & 0x02)
735
+						missing.window1[0] = 1;
736
+				#endif
737
+				}
738
+
739
+				break;
740
+
741
+			case 0x2124: // W34SEL
742
+				if (Byte != Memory.FillRAM[0x2124])
743
+				{
744
+					//FLUSH_REDRAW();
745
+					PPU.ClipWindow1Enable[2] = !!(Byte & 0x02);
746
+					PPU.ClipWindow1Enable[3] = !!(Byte & 0x20);
747
+					PPU.ClipWindow2Enable[2] = !!(Byte & 0x08);
748
+					PPU.ClipWindow2Enable[3] = !!(Byte & 0x80);
749
+					PPU.ClipWindow1Inside[2] = !(Byte & 0x01);
750
+					PPU.ClipWindow1Inside[3] = !(Byte & 0x10);
751
+					PPU.ClipWindow2Inside[2] = !(Byte & 0x04);
752
+					PPU.ClipWindow2Inside[3] = !(Byte & 0x40);
753
+					PPU.RecomputeClipWindows = true;
754
+				#ifdef DEBUGGER
755
+					if (Byte & 0x80)
756
+						missing.window2[3] = 1;
757
+					if (Byte & 0x20)
758
+						missing.window1[3] = 1;
759
+					if (Byte & 0x08)
760
+						missing.window2[2] = 1;
761
+					if (Byte & 0x02)
762
+						missing.window1[2] = 1;
763
+				#endif
764
+				}
765
+
766
+				break;
767
+
768
+			case 0x2125: // WOBJSEL
769
+				if (Byte != Memory.FillRAM[0x2125])
770
+				{
771
+					//FLUSH_REDRAW();
772
+					PPU.ClipWindow1Enable[4] = !!(Byte & 0x02);
773
+					PPU.ClipWindow1Enable[5] = !!(Byte & 0x20);
774
+					PPU.ClipWindow2Enable[4] = !!(Byte & 0x08);
775
+					PPU.ClipWindow2Enable[5] = !!(Byte & 0x80);
776
+					PPU.ClipWindow1Inside[4] = !(Byte & 0x01);
777
+					PPU.ClipWindow1Inside[5] = !(Byte & 0x10);
778
+					PPU.ClipWindow2Inside[4] = !(Byte & 0x04);
779
+					PPU.ClipWindow2Inside[5] = !(Byte & 0x40);
780
+					PPU.RecomputeClipWindows = true;
781
+				#ifdef DEBUGGER
782
+					if (Byte & 0x80)
783
+						missing.window2[5] = 1;
784
+					if (Byte & 0x20)
785
+						missing.window1[5] = 1;
786
+					if (Byte & 0x08)
787
+						missing.window2[4] = 1;
788
+					if (Byte & 0x02)
789
+						missing.window1[4] = 1;
790
+				#endif
791
+				}
792
+
793
+				break;
794
+
795
+			case 0x2126: // WH0
796
+				if (Byte != Memory.FillRAM[0x2126])
797
+				{
798
+					//FLUSH_REDRAW();
799
+					PPU.Window1Left = Byte;
800
+					PPU.RecomputeClipWindows = true;
801
+				}
802
+
803
+				break;
804
+
805
+			case 0x2127: // WH1
806
+				if (Byte != Memory.FillRAM[0x2127])
807
+				{
808
+					//FLUSH_REDRAW();
809
+					PPU.Window1Right = Byte;
810
+					PPU.RecomputeClipWindows = true;
811
+				}
812
+
813
+				break;
814
+
815
+			case 0x2128: // WH2
816
+				if (Byte != Memory.FillRAM[0x2128])
817
+				{
818
+					//FLUSH_REDRAW();
819
+					PPU.Window2Left = Byte;
820
+					PPU.RecomputeClipWindows = true;
821
+				}
822
+
823
+				break;
824
+
825
+			case 0x2129: // WH3
826
+				if (Byte != Memory.FillRAM[0x2129])
827
+				{
828
+					//FLUSH_REDRAW();
829
+					PPU.Window2Right = Byte;
830
+					PPU.RecomputeClipWindows = true;
831
+				}
832
+
833
+				break;
834
+
835
+			case 0x212a: // WBGLOG
836
+				if (Byte != Memory.FillRAM[0x212a])
837
+				{
838
+					//FLUSH_REDRAW();
839
+					PPU.ClipWindowOverlapLogic[0] = (Byte & 0x03);
840
+					PPU.ClipWindowOverlapLogic[1] = (Byte & 0x0c) >> 2;
841
+					PPU.ClipWindowOverlapLogic[2] = (Byte & 0x30) >> 4;
842
+					PPU.ClipWindowOverlapLogic[3] = (Byte & 0xc0) >> 6;
843
+					PPU.RecomputeClipWindows = true;
844
+				}
845
+
846
+				break;
847
+
848
+			case 0x212b: // WOBJLOG
849
+				if (Byte != Memory.FillRAM[0x212b])
850
+				{
851
+					//FLUSH_REDRAW();
852
+					PPU.ClipWindowOverlapLogic[4] = (Byte & 0x03);
853
+					PPU.ClipWindowOverlapLogic[5] = (Byte & 0x0c) >> 2;
854
+					PPU.RecomputeClipWindows = true;
855
+				}
856
+
857
+				break;
858
+
859
+			case 0x212c: // TM
860
+				if (Byte != Memory.FillRAM[0x212c])
861
+				{
862
+					//FLUSH_REDRAW();
863
+					PPU.RecomputeClipWindows = true;
864
+				}
865
+
866
+				break;
867
+
868
+			case 0x212d: // TS
869
+				if (Byte != Memory.FillRAM[0x212d])
870
+				{
871
+					//FLUSH_REDRAW();
872
+					PPU.RecomputeClipWindows = true;
873
+				#ifdef DEBUGGER
874
+					if (Byte & 0x1f)
875
+						missing.subscreen = 1;
876
+				#endif
877
+				}
878
+
879
+				break;
880
+
881
+			case 0x212e: // TMW
882
+				if (Byte != Memory.FillRAM[0x212e])
883
+				{
884
+					//FLUSH_REDRAW();
885
+					PPU.RecomputeClipWindows = true;
886
+				}
887
+
888
+				break;
889
+
890
+			case 0x212f: // TSW
891
+				if (Byte != Memory.FillRAM[0x212f])
892
+				{
893
+					//FLUSH_REDRAW();
894
+					PPU.RecomputeClipWindows = true;
895
+				}
896
+
897
+				break;
898
+
899
+			case 0x2130: // CGWSEL
900
+				if (Byte != Memory.FillRAM[0x2130])
901
+				{
902
+					//FLUSH_REDRAW();
903
+					PPU.RecomputeClipWindows = true;
904
+				#ifdef DEBUGGER
905
+					if ((Byte & 1) && (PPU.BGMode == 3 || PPU.BGMode == 4 || PPU.BGMode == 7))
906
+						missing.direct = 1;
907
+				#endif
908
+				}
909
+
910
+				break;
911
+
912
+			case 0x2131: // CGADSUB
913
+				if (Byte != Memory.FillRAM[0x2131])
914
+				{
915
+					//FLUSH_REDRAW();
916
+				#ifdef DEBUGGER
917
+					if (Byte & 0x80)
918
+					{
919
+						if (Memory.FillRAM[0x2130] & 0x02)
920
+							missing.subscreen_sub = 1;
921
+						else
922
+							missing.fixed_colour_sub = 1;
923
+					}
924
+					else
925
+					{
926
+						if (Memory.FillRAM[0x2130] & 0x02)
927
+							missing.subscreen_add = 1;
928
+						else
929
+							missing.fixed_colour_add = 1;
930
+					}
931
+				#endif
932
+				}
933
+
934
+				break;
935
+
936
+			case 0x2132: // COLDATA
937
+				if (Byte != Memory.FillRAM[0x2132])
938
+				{
939
+					//FLUSH_REDRAW();
940
+					if (Byte & 0x80)
941
+						PPU.FixedColourBlue  = Byte & 0x1f;
942
+					if (Byte & 0x40)
943
+						PPU.FixedColourGreen = Byte & 0x1f;
944
+					if (Byte & 0x20)
945
+						PPU.FixedColourRed   = Byte & 0x1f;
946
+				}
947
+
948
+				break;
949
+
950
+			case 0x2133: // SETINI
951
+				if (Byte != Memory.FillRAM[0x2133])
952
+				{
953
+					if ((Memory.FillRAM[0x2133] ^ Byte) & 8)
954
+					{
955
+						//FLUSH_REDRAW();
956
+						IPPU.PseudoHires = !!(Byte & 8);
957
+					}
958
+
959
+					if (Byte & 0x04)
960
+					{
961
+						PPU.ScreenHeight = SNES_HEIGHT_EXTENDED;
962
+						if (IPPU.DoubleHeightPixels)
963
+							IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1;
964
+						else
965
+							IPPU.RenderedScreenHeight = PPU.ScreenHeight;
966
+					#ifdef DEBUGGER
967
+						missing.lines_239 = 1;
968
+					#endif
969
+					}
970
+					else
971
+						PPU.ScreenHeight = SNES_HEIGHT;
972
+
973
+					if ((Memory.FillRAM[0x2133] ^ Byte) & 3)
974
+					{
975
+						//FLUSH_REDRAW();
976
+						if ((Memory.FillRAM[0x2133] ^ Byte) & 2)
977
+							IPPU.OBJChanged = true;
978
+						IPPU.Interlace = Byte & 1;
979
+						IPPU.InterlaceOBJ = !!(Byte & 2);
980
+					}
981
+				#ifdef DEBUGGER
982
+					if (Byte & 0x40)
983
+						missing.mode7_bgmode = 1;
984
+					if (Byte & 0x08)
985
+						missing.pseudo_512 = 1;
986
+					if (Byte & 0x02)
987
+						missing.sprite_double_height = 1;
988
+					if (Byte & 0x01)
989
+						missing.interlace = 1;
990
+				#endif
991
+				}
992
+
993
+				break;
994
+
995
+			case 0x2134: // MPYL
996
+			case 0x2135: // MPYM
997
+			case 0x2136: // MPYH
998
+			case 0x2137: // SLHV
999
+			case 0x2138: // OAMDATAREAD
1000
+			case 0x2139: // VMDATALREAD
1001
+			case 0x213a: // VMDATAHREAD
1002
+			case 0x213b: // CGDATAREAD
1003
+			case 0x213c: // OPHCT
1004
+			case 0x213d: // OPVCT
1005
+			case 0x213e: // STAT77
1006
+			case 0x213f: // STAT78
1007
+				return;
1008
+
1009
+			case 0x2180: // WMDATA
1010
+				if (!CPU.InWRAMDMAorHDMA)
1011
+					REGISTER_2180(Byte);
1012
+				break;
1013
+
1014
+			case 0x2181: // WMADDL
1015
+				if (!CPU.InWRAMDMAorHDMA)
1016
+				{
1017
+					PPU.WRAM &= 0x1ff00;
1018
+					PPU.WRAM |= Byte;
1019
+				}
1020
+
1021
+				break;
1022
+
1023
+			case 0x2182: // WMADDM
1024
+				if (!CPU.InWRAMDMAorHDMA)
1025
+				{
1026
+					PPU.WRAM &= 0x100ff;
1027
+					PPU.WRAM |= Byte << 8;
1028
+				}
1029
+
1030
+				break;
1031
+
1032
+			case 0x2183: // WMADDH
1033
+				if (!CPU.InWRAMDMAorHDMA)
1034
+				{
1035
+					PPU.WRAM &= 0x0ffff;
1036
+					PPU.WRAM |= Byte << 16;
1037
+					PPU.WRAM &= 0x1ffff;
1038
+				}
1039
+
1040
+				break;
1041
+		}
1042
+	}
1043
+	/*else
1044
+	{
1045
+		if (Settings.SuperFX && Address >= 0x3000 && Address <= 0x32ff)
1046
+		{
1047
+			S9xSetSuperFX(Byte, Address);
1048
+			return;
1049
+		}
1050
+		else
1051
+		if (Settings.SA1     && Address >= 0x2200)
1052
+		{
1053
+			if (Address <= 0x23ff)
1054
+				S9xSetSA1(Byte, Address);
1055
+			else
1056
+				Memory.FillRAM[Address] = Byte;
1057
+			return;
1058
+		}
1059
+		else
1060
+		if (Settings.BS      && Address >= 0x2188 && Address <= 0x219f)
1061
+			S9xSetBSXPPU(Byte, Address);
1062
+		else
1063
+		if (Settings.SRTC    && Address == 0x2801)
1064
+			S9xSetSRTC(Byte, Address);
1065
+	#ifdef DEBUGGER
1066
+		else
1067
+		{
1068
+			missing.unknownppu_write = Address;
1069
+			if (Settings.TraceUnknownRegisters)
1070
+			{
1071
+				sprintf(String, "Unknown register write: $%02X->$%04X\n", Byte, Address);
1072
+				S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String);
1073
+			}
1074
+		}
1075
+	#endif
1076
+	}*/
1077
+
1078
+	Memory.FillRAM[Address] = Byte;
1079
+}
1080
+
1081
+uint8_t S9xGetPPU (uint16_t Address)
1082
+{
1083
+	// MAP_PPU: $2000-$3FFF
1084
+
1085
+	if (Address < 0x2100)
1086
+		return OpenBus;
1087
+
1088
+	if (CPU.InDMAorHDMA)
1089
+	{
1090
+		if (CPU.CurrentDMAorHDMAChannel >= 0 && !DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer)
1091
+		{
1092
+			// S9xGetPPU() is called to read from DMA[].AAddress
1093
+			if ((Address & 0xff00) == 0x2100)
1094
+				// Cannot access to Address Bus B ($2100-$21FF) via (H)DMA
1095
+				return OpenBus;
1096
+			else
1097
+				// $2200-$3FFF are connected to Address Bus A
1098
+				// SA1, SuperFX and SRTC are mapped here
1099
+				// I don't bother for now...
1100
+				return OpenBus;
1101
+		}
1102
+		else
1103
+		{
1104
+			// S9xGetPPU() is called to write to $21xx
1105
+			// Take care of DMA wrapping
1106
+			if (Address > 0x21ff)
1107
+				Address = 0x2100 + (Address & 0xff);
1108
+		}
1109
+	}
1110
+
1111
+	if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3
1112
+		// read_port will run the APU until given APU time before reading value
1113
+		return S9xAPUReadPort(Address & 3);
1114
+	else
1115
+	if (Address <= 0x2183)
1116
+    {
1117
+		uint8_t	byte;
1118
+
1119
+		switch (Address)
1120
+		{
1121
+			case 0x2104: // OAMDATA
1122
+			case 0x2105: // BGMODE
1123
+			case 0x2106: // MOSAIC
1124
+			case 0x2108: // BG2SC
1125
+			case 0x2109: // BG3SC
1126
+			case 0x210a: // BG4SC
1127
+			case 0x2114: // BG4VOFS
1128
+			case 0x2115: // VMAIN
1129
+			case 0x2116: // VMADDL
1130
+			case 0x2118: // VMDATAL
1131
+			case 0x2119: // VMDATAH
1132
+			case 0x211a: // M7SEL
1133
+			case 0x2124: // W34SEL
1134
+			case 0x2125: // WOBJSEL
1135
+			case 0x2126: // WH0
1136
+			case 0x2128: // WH2
1137
+			case 0x2129: // WH3
1138
+			case 0x212a: // WBGLOG
1139
+				return PPU.OpenBus1;
1140
+
1141
+			case 0x2134: // MPYL
1142
+			case 0x2135: // MPYM
1143
+			case 0x2136: // MPYH
1144
+				if (PPU.Need16x8Mulitply)
1145
+				{
1146
+					int32_t r = (int32_t) PPU.MatrixA * (int32_t) (PPU.MatrixB >> 8);
1147
+					Memory.FillRAM[0x2134] = (uint8_t) r;
1148
+					Memory.FillRAM[0x2135] = (uint8_t) (r >> 8);
1149
+					Memory.FillRAM[0x2136] = (uint8_t) (r >> 16);
1150
+					PPU.Need16x8Mulitply = false;
1151
+				}
1152
+			#ifdef DEBUGGER
1153
+				missing.matrix_multiply = 1;
1154
+			#endif
1155
+				return (PPU.OpenBus1 = Memory.FillRAM[Address]);
1156
+
1157
+			case 0x2137: // SLHV
1158
+				S9xLatchCounters(0);
1159
+				return OpenBus;
1160
+
1161
+			case 0x2138: // OAMDATAREAD
1162
+				if (PPU.OAMAddr & 0x100)
1163
+				{
1164
+					if (!(PPU.OAMFlip & 1))
1165
+						byte = PPU.OAMData[(PPU.OAMAddr & 0x10f) << 1];
1166
+					else
1167
+					{
1168
+						byte = PPU.OAMData[((PPU.OAMAddr & 0x10f) << 1) + 1];
1169
+						PPU.OAMAddr = (PPU.OAMAddr + 1) & 0x1ff;
1170
+						if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
1171
+						{
1172
+							PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1;
1173
+							IPPU.OBJChanged = true;
1174
+						#ifdef DEBUGGER
1175
+							missing.sprite_priority_rotation = 1;
1176
+						#endif
1177
+						}
1178
+					}
1179
+				}
1180
+				else
1181
+				{
1182
+					if (!(PPU.OAMFlip & 1))
1183
+						byte = PPU.OAMData[PPU.OAMAddr << 1];
1184
+					else
1185
+					{
1186
+						byte = PPU.OAMData[(PPU.OAMAddr << 1) + 1];
1187
+						++PPU.OAMAddr;
1188
+						if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
1189
+						{
1190
+							PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1;
1191
+							IPPU.OBJChanged = true;
1192
+						#ifdef DEBUGGER
1193
+							missing.sprite_priority_rotation = 1;
1194
+						#endif
1195
+						}
1196
+					}
1197
+				}
1198
+
1199
+				PPU.OAMFlip ^= 1;
1200
+			#ifdef DEBUGGER
1201
+				missing.oam_read = 1;
1202
+			#endif
1203
+				return (PPU.OpenBus1 = byte);
1204
+
1205
+			case 0x2139: // VMDATALREAD
1206
+				byte = IPPU.VRAMReadBuffer & 0xff;
1207
+				if (!PPU.VMA.High)
1208
+				{
1209
+					if (PPU.VMA.FullGraphicCount)
1210
+					{
1211
+						uint32_t addr = PPU.VMA.Address;
1212
+						uint32_t rem = addr & PPU.VMA.Mask1;
1213
+						uint32_t address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
1214
+						IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff));
1215
+					}
1216
+					else
1217
+						IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
1218
+
1219
+					PPU.VMA.Address += PPU.VMA.Increment;
1220
+				}
1221
+
1222
+			#ifdef DEBUGGER
1223
+				missing.vram_read = 1;
1224
+			#endif
1225
+				return (PPU.OpenBus1 = byte);
1226
+
1227
+			case 0x213a: // VMDATAHREAD
1228
+				byte = (IPPU.VRAMReadBuffer >> 8) & 0xff;
1229
+				if (PPU.VMA.High)
1230
+				{
1231
+					if (PPU.VMA.FullGraphicCount)
1232
+					{
1233
+						uint32_t addr = PPU.VMA.Address;
1234
+						uint32_t rem = addr & PPU.VMA.Mask1;
1235
+						uint32_t address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
1236
+						IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff));
1237
+					}
1238
+					else
1239
+						IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
1240
+
1241
+					PPU.VMA.Address += PPU.VMA.Increment;
1242
+				}
1243
+			#ifdef DEBUGGER
1244
+				missing.vram_read = 1;
1245
+			#endif
1246
+				return (PPU.OpenBus1 = byte);
1247
+
1248
+			case 0x213b: // CGDATAREAD
1249
+				if (PPU.CGFLIPRead)
1250
+					byte = (PPU.OpenBus2 & 0x80) | ((PPU.CGDATA[PPU.CGADD++] >> 8) & 0x7f);
1251
+				else
1252
+					byte = PPU.CGDATA[PPU.CGADD] & 0xff;
1253
+				PPU.CGFLIPRead ^= 1;
1254
+			#ifdef DEBUGGER
1255
+				missing.cgram_read = 1;
1256
+			#endif
1257
+				return (PPU.OpenBus2 = byte);
1258
+
1259
+			case 0x213c: // OPHCT
1260
+				S9xTryGunLatch(false);
1261
+				if (PPU.HBeamFlip)
1262
+					byte = (PPU.OpenBus2 & 0xfe) | ((PPU.HBeamPosLatched >> 8) & 0x01);
1263
+				else
1264
+					byte = (uint8_t) PPU.HBeamPosLatched;
1265
+				PPU.HBeamFlip ^= 1;
1266
+			#ifdef DEBUGGER
1267
+				missing.h_counter_read = 1;
1268
+			#endif
1269
+				return (PPU.OpenBus2 = byte);
1270
+
1271
+			case 0x213d: // OPVCT
1272
+				S9xTryGunLatch(false);
1273
+				if (PPU.VBeamFlip)
1274
+					byte = (PPU.OpenBus2 & 0xfe) | ((PPU.VBeamPosLatched >> 8) & 0x01);
1275
+				else
1276
+					byte = (uint8_t) PPU.VBeamPosLatched;
1277
+				PPU.VBeamFlip ^= 1;
1278
+			#ifdef DEBUGGER
1279
+				missing.v_counter_read = 1;
1280
+			#endif
1281
+				return (PPU.OpenBus2 = byte);
1282
+
1283
+			case 0x213e: // STAT77
1284
+				//FLUSH_REDRAW();
1285
+				byte = (PPU.OpenBus1 & 0x10) | PPU.RangeTimeOver | Model->_5C77;
1286
+				return (PPU.OpenBus1 = byte);
1287
+
1288
+			case 0x213f: // STAT78
1289
+				S9xTryGunLatch(false);
1290
+				PPU.VBeamFlip = PPU.HBeamFlip = 0;
1291
+				byte = (PPU.OpenBus2 & 0x20) | (Memory.FillRAM[0x213f] & 0xc0) | (Settings.PAL ? 0x10 : 0) | Model->_5C78;
1292
+				Memory.FillRAM[0x213f] &= ~0x40;
1293
+				return (PPU.OpenBus2 = byte);
1294
+
1295
+			case 0x2180: // WMDATA
1296
+				if (!CPU.InWRAMDMAorHDMA)
1297
+				{
1298
+					byte = Memory.RAM[PPU.WRAM++];
1299
+					PPU.WRAM &= 0x1ffff;
1300
+				}
1301
+				else
1302
+					byte = OpenBus;
1303
+			#ifdef DEBUGGER
1304
+				missing.wram_read = 1;
1305
+			#endif
1306
+				return byte;
1307
+
1308
+			default:
1309
+				return OpenBus;
1310
+		}
1311
+	}
1312
+	else
1313
+    {
1314
+		/*if (Settings.SuperFX && Address >= 0x3000 && Address <= 0x32ff)
1315
+			return S9xGetSuperFX(Address);
1316
+		else
1317
+		if (Settings.SA1     && Address >= 0x2200)
1318
+			return S9xGetSA1(Address);
1319
+		else
1320
+		if (Settings.BS      && Address >= 0x2188 && Address <= 0x219f)
1321
+			return S9xGetBSXPPU(Address);
1322
+		else	
1323
+		if (Settings.SRTC    && Address == 0x2800)
1324
+			return S9xGetSRTC(Address);
1325
+		else*/
1326
+		switch (Address)
1327
+		{
1328
+			case 0x21c2:
1329
+				if (Model->_5C77 == 2)
1330
+					return 0x20;
1331
+				return OpenBus;
1332
+
1333
+			case 0x21c3:
1334
+				if (Model->_5C77 == 2)
1335
+					return 0;
1336
+				return OpenBus;
1337
+
1338
+			default:
1339
+				return OpenBus;
1340
+		}
1341
+	}
1342
+}
1343
+
1344
+void S9xSetCPU (uint8_t Byte, uint16_t Address)
1345
+{
1346
+	if (Address < 0x4200)
1347
+	{
1348
+		/*switch (Address)
1349
+		{
1350
+			case 0x4016: // JOYSER0
1351
+				S9xSetJoypadLatch(Byte & 1);
1352
+				break;
1353
+
1354
+			case 0x4017: // JOYSER1
1355
+				return;
1356
+
1357
+			default:
1358
+				break;
1359
+		}*/
1360
+	}
1361
+	else
1362
+	if ((Address & 0xff80) == 0x4300)
1363
+	{
1364
+		if (CPU.InDMAorHDMA)
1365
+			return;
1366
+
1367
+		int	d = (Address >> 4) & 0x7;
1368
+
1369
+		switch (Address & 0xf)
1370
+		{
1371
+			case 0x0: // 0x43x0: DMAPx
1372
+				DMA[d].ReverseTransfer        = (Byte & 0x80) ? true : false;
1373
+				DMA[d].HDMAIndirectAddressing = (Byte & 0x40) ? true : false;
1374
+				DMA[d].UnusedBit43x0          = (Byte & 0x20) ? true : false;
1375
+				DMA[d].AAddressDecrement      = (Byte & 0x10) ? true : false;
1376
+				DMA[d].AAddressFixed          = (Byte & 0x08) ? true : false;
1377
+				DMA[d].TransferMode           = (Byte & 7);
1378
+				return;
1379
+
1380
+			case 0x1: // 0x43x1: BBADx
1381
+				DMA[d].BAddress = Byte;
1382
+				return;
1383
+
1384
+			case 0x2: // 0x43x2: A1TxL
1385
+				DMA[d].AAddress &= 0xff00;
1386
+				DMA[d].AAddress |= Byte;
1387
+				return;
1388
+
1389
+			case 0x3: // 0x43x3: A1TxH
1390
+				DMA[d].AAddress &= 0xff;
1391
+				DMA[d].AAddress |= Byte << 8;
1392
+				return;
1393
+
1394
+			case 0x4: // 0x43x4: A1Bx
1395
+				DMA[d].ABank = Byte;
1396
+				HDMAMemPointers[d] = NULL;
1397
+				return;
1398
+
1399
+			case 0x5: // 0x43x5: DASxL
1400
+				DMA[d].DMACount_Or_HDMAIndirectAddress &= 0xff00;
1401
+				DMA[d].DMACount_Or_HDMAIndirectAddress |= Byte;
1402
+				HDMAMemPointers[d] = NULL;
1403
+				return;
1404
+
1405
+			case 0x6: // 0x43x6: DASxH
1406
+				DMA[d].DMACount_Or_HDMAIndirectAddress &= 0xff;
1407
+				DMA[d].DMACount_Or_HDMAIndirectAddress |= Byte << 8;
1408
+				HDMAMemPointers[d] = NULL;
1409
+				return;
1410
+
1411
+			case 0x7: // 0x43x7: DASBx
1412
+				DMA[d].IndirectBank = Byte;
1413
+				HDMAMemPointers[d] = NULL;
1414
+				return;
1415
+
1416
+			case 0x8: // 0x43x8: A2AxL
1417
+				DMA[d].Address &= 0xff00;
1418
+				DMA[d].Address |= Byte;
1419
+				HDMAMemPointers[d] = NULL;
1420
+				return;
1421
+
1422
+			case 0x9: // 0x43x9: A2AxH
1423
+				DMA[d].Address &= 0xff;
1424
+				DMA[d].Address |= Byte << 8;
1425
+				HDMAMemPointers[d] = NULL;
1426
+				return;
1427
+
1428
+			case 0xa: // 0x43xa: NLTRx
1429
+				if (Byte & 0x7f)
1430
+				{
1431
+					DMA[d].LineCount = Byte & 0x7f;
1432
+					DMA[d].Repeat = !(Byte & 0x80);
1433
+				}
1434
+				else
1435
+				{
1436
+					DMA[d].LineCount = 128;
1437
+					DMA[d].Repeat = !!(Byte & 0x80);
1438
+				}
1439
+
1440
+				return;
1441
+
1442
+			case 0xb: // 0x43xb: ????x
1443
+			case 0xf: // 0x43xf: mirror of 0x43xb
1444
+				DMA[d].UnknownByte = Byte;
1445
+				return;
1446
+
1447
+			default:
1448
+				break;
1449
+		}
1450
+	}
1451
+	else
1452
+	{
1453
+		uint16_t	pos;
1454
+
1455
+		switch (Address)
1456
+		{
1457
+			case 0x4200: // NMITIMEN
1458
+				if (Byte & 0x20)
1459
+				{
1460
+					PPU.VTimerEnabled = true;
1461
+				#ifdef DEBUGGER
1462
+					missing.virq = 1;
1463
+					missing.virq_pos = PPU.IRQVBeamPos;
1464
+				#endif
1465
+				}
1466
+				else
1467
+					PPU.VTimerEnabled = false;
1468
+
1469
+				if (Byte & 0x10)
1470
+				{
1471
+					PPU.HTimerEnabled = true;
1472
+				#ifdef DEBUGGER
1473
+					missing.hirq = 1;
1474
+					missing.hirq_pos = PPU.IRQHBeamPos;
1475
+				#endif
1476
+				}
1477
+				else
1478
+					PPU.HTimerEnabled = false;
1479
+
1480
+				if (CPU.IRQLine && !PPU.HTimerEnabled && PPU.VTimerEnabled)
1481
+					CPU.IRQTransition = true;
1482
+
1483
+				if (!PPU.HTimerEnabled && !PPU.VTimerEnabled)
1484
+				{
1485
+					CPU.IRQLine = false;
1486
+					CPU.IRQTransition = false;
1487
+				}
1488
+
1489
+				// NMI can trigger immediately during VBlank as long as NMI_read ($4210) wasn't cleard.
1490
+				if ((Byte & 0x80) && !(Memory.FillRAM[0x4200] & 0x80) &&
1491
+					(CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) && (Memory.FillRAM[0x4210] & 0x80))
1492
+				{
1493
+					// FIXME: triggered at HC+=6, checked just before the final CPU cycle,
1494
+					// then, when to call S9xOpcode_NMI()?
1495
+					CPU.NMILine = true;
1496
+					Timings.NMITriggerPos = CPU.Cycles + 6 + 6;
1497
+				}
1498
+
1499
+				break;
1500
+
1501
+			case 0x4201: // WRIO
1502
+				if ((Byte & 0x80) == 0 && (Memory.FillRAM[0x4213] & 0x80) == 0x80)
1503
+					S9xLatchCounters(1);
1504
+				else
1505
+					S9xTryGunLatch((Byte & 0x80) ? true : false);
1506
+				Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = Byte;
1507
+				break;
1508
+
1509
+			case 0x4202: // WRMPYA
1510
+				break;
1511
+
1512
+			case 0x4203: // WRMPYB
1513
+			{
1514
+				uint32_t res = Memory.FillRAM[0x4202] * Byte;
1515
+				// FIXME: The update occurs 8 machine cycles after $4203 is set.
1516
+				Memory.FillRAM[0x4216] = (uint8_t) res;
1517
+				Memory.FillRAM[0x4217] = (uint8_t) (res >> 8);
1518
+				break;
1519
+			}
1520
+
1521
+			case 0x4204: // WRDIVL
1522
+			case 0x4205: // WRDIVH
1523
+				break;
1524
+
1525
+			case 0x4206: // WRDIVB
1526
+			{
1527
+				uint16_t a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8);
1528
+				uint16_t div = Byte ? a / Byte : 0xffff;
1529
+				uint16_t rem = Byte ? a % Byte : a;
1530
+				// FIXME: The update occurs 16 machine cycles after $4206 is set.
1531
+				Memory.FillRAM[0x4214] = (uint8_t) div;
1532
+				Memory.FillRAM[0x4215] = div >> 8;
1533
+				Memory.FillRAM[0x4216] = (uint8_t) rem;
1534
+				Memory.FillRAM[0x4217] = rem >> 8;
1535
+				break;
1536
+			}
1537
+
1538
+			case 0x4207: // HTIMEL
1539
+				pos = PPU.IRQHBeamPos;
1540
+				PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff00) | Byte;
1541
+				if (PPU.IRQHBeamPos != pos)
1542
+					S9xUpdateHVTimerPosition();
1543
+			#ifdef DEBUGGER
1544
+				missing.hirq_pos = PPU.IRQHBeamPos;
1545
+			#endif
1546
+				break;
1547
+
1548
+			case 0x4208: // HTIMEH
1549
+				pos = PPU.IRQHBeamPos;
1550
+				PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff) | ((Byte & 1) << 8);
1551
+				if (PPU.IRQHBeamPos != pos)
1552
+					S9xUpdateHVTimerPosition();
1553
+			#ifdef DEBUGGER
1554
+				missing.hirq_pos = PPU.IRQHBeamPos;
1555
+			#endif
1556
+				break;
1557
+
1558
+			case 0x4209: // VTIMEL
1559
+				pos = PPU.IRQVBeamPos;
1560
+				PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff00) | Byte;
1561
+				if (PPU.IRQVBeamPos != pos)
1562
+					S9xUpdateHVTimerPosition();
1563
+			#ifdef DEBUGGER
1564
+				missing.virq_pos = PPU.IRQVBeamPos;
1565
+			#endif
1566
+				break;
1567
+
1568
+			case 0x420a: // VTIMEH
1569
+				pos = PPU.IRQVBeamPos;
1570
+				PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff) | ((Byte & 1) << 8);
1571
+				if (PPU.IRQVBeamPos != pos)
1572
+					S9xUpdateHVTimerPosition();
1573
+			#ifdef DEBUGGER
1574
+				missing.virq_pos = PPU.IRQVBeamPos;
1575
+			#endif
1576
+				break;
1577
+
1578
+			case 0x420b: // MDMAEN
1579
+				if (CPU.InDMAorHDMA)
1580
+					return;
1581
+				// XXX: Not quite right...
1582
+				if (Byte)
1583
+					CPU.Cycles += Timings.DMACPUSync;
1584
+				if (Byte & 0x01)
1585
+					S9xDoDMA(0);
1586
+				if (Byte & 0x02)
1587
+					S9xDoDMA(1);
1588
+				if (Byte & 0x04)
1589
+					S9xDoDMA(2);
1590
+				if (Byte & 0x08)
1591
+					S9xDoDMA(3);
1592
+				if (Byte & 0x10)
1593
+					S9xDoDMA(4);
1594
+				if (Byte & 0x20)
1595
+					S9xDoDMA(5);
1596
+				if (Byte & 0x40)
1597
+					S9xDoDMA(6);
1598
+				if (Byte & 0x80)
1599
+					S9xDoDMA(7);
1600
+			#ifdef DEBUGGER
1601
+				missing.dma_this_frame = Byte;
1602
+				missing.dma_channels = Byte;
1603
+			#endif
1604
+				break;
1605
+
1606
+			case 0x420c: // HDMAEN
1607
+				if (CPU.InDMAorHDMA)
1608
+					return;
1609
+				Memory.FillRAM[0x420c] = Byte;
1610
+				// Yoshi's Island, Genjyu Ryodan, Mortal Kombat, Tales of Phantasia
1611
+				PPU.HDMA = Byte & ~PPU.HDMAEnded;
1612
+			#ifdef DEBUGGER
1613
+				missing.hdma_this_frame |= Byte;
1614
+				missing.hdma_channels |= Byte;
1615
+			#endif
1616
+				break;
1617
+
1618
+			case 0x420d: // MEMSEL
1619
+				if ((Byte & 1) != (Memory.FillRAM[0x420d] & 1))
1620
+				{
1621
+					if (Byte & 1)
1622
+					{
1623
+						CPU.FastROMSpeed = ONE_CYCLE;
1624
+					#ifdef DEBUGGER
1625
+						missing.fast_rom = 1;
1626
+					#endif
1627
+					}
1628
+					else
1629
+						CPU.FastROMSpeed = SLOW_ONE_CYCLE;
1630
+				}
1631
+
1632
+				break;
1633
+
1634
+			case 0x4210: // RDNMI
1635
+			case 0x4211: // TIMEUP
1636
+			case 0x4212: // HVBJOY
1637
+			case 0x4213: // RDIO
1638
+			case 0x4214: // RDDIVL
1639
+			case 0x4215: // RDDIVH
1640
+			case 0x4216: // RDMPYL
1641
+			case 0x4217: // RDMPYH
1642
+			case 0x4218: // JOY1L
1643
+			case 0x4219: // JOY1H
1644
+			case 0x421a: // JOY2L
1645
+			case 0x421b: // JOY2H
1646
+			case 0x421c: // JOY3L
1647
+			case 0x421d: // JOY3H
1648
+			case 0x421e: // JOY4L
1649
+			case 0x421f: // JOY4H
1650
+				return;
1651
+
1652
+			default:
1653
+				/*if (Settings.SPC7110 && Address >= 0x4800)
1654
+					S9xSetSPC7110(Byte, Address);
1655
+				else*/
1656
+				if (Settings.SDD1 && Address >= 0x4804 && Address <= 0x4807)
1657
+					S9xSetSDD1MemoryMap(Address - 0x4804, Byte & 7);
1658
+				break;
1659
+		}
1660
+	}
1661
+
1662
+	Memory.FillRAM[Address] = Byte;
1663
+}
1664
+
1665
+uint8_t S9xGetCPU (uint16_t Address)
1666
+{
1667
+	if (Address < 0x4200)
1668
+	{
1669
+	#ifdef SNES_JOY_READ_CALLBACKS
1670
+		extern bool pad_read;
1671
+		if (Address == 0x4016 || Address == 0x4017)
1672
+		{
1673
+			S9xOnSNESPadRead();
1674
+			pad_read = true;
1675
+		}
1676
+	#endif
1677
+
1678
+		/*switch (Address)
1679
+		{
1680
+			case 0x4016: // JOYSER0
1681
+			case 0x4017: // JOYSER1
1682
+				return S9xReadJOYSERn(Address);
1683
+
1684
+			default:*/
1685
+				return OpenBus;
1686
+		//}
1687
+	}
1688
+	else
1689
+	if ((Address & 0xff80) == 0x4300)
1690
+	{
1691
+		if (CPU.InDMAorHDMA)
1692
+			return OpenBus;
1693
+
1694
+		int	d = (Address >> 4) & 0x7;
1695
+
1696
+		switch (Address & 0xf)
1697
+		{
1698
+			case 0x0: // 0x43x0: DMAPx
1699
+				return  (DMA[d].ReverseTransfer        ? 0x80 : 0) |
1700
+						(DMA[d].HDMAIndirectAddressing ? 0x40 : 0) |
1701
+						(DMA[d].UnusedBit43x0          ? 0x20 : 0) |
1702
+						(DMA[d].AAddressDecrement      ? 0x10 : 0) |
1703
+						(DMA[d].AAddressFixed          ? 0x08 : 0) |
1704
+						(DMA[d].TransferMode & 7);
1705
+
1706
+			case 0x1: // 0x43x1: BBADx
1707
+				return DMA[d].BAddress;
1708
+
1709
+			case 0x2: // 0x43x2: A1TxL
1710
+				return DMA[d].AAddress & 0xff;
1711
+
1712
+			case 0x3: // 0x43x3: A1TxH
1713
+				return DMA[d].AAddress >> 8;
1714
+
1715
+			case 0x4: // 0x43x4: A1Bx
1716
+				return DMA[d].ABank;
1717
+
1718
+			case 0x5: // 0x43x5: DASxL
1719
+				return DMA[d].DMACount_Or_HDMAIndirectAddress & 0xff;
1720
+
1721
+			case 0x6: // 0x43x6: DASxH
1722
+				return DMA[d].DMACount_Or_HDMAIndirectAddress >> 8;
1723
+
1724
+			case 0x7: // 0x43x7: DASBx
1725
+				return DMA[d].IndirectBank;
1726
+
1727
+			case 0x8: // 0x43x8: A2AxL
1728
+				return DMA[d].Address & 0xff;
1729
+
1730
+			case 0x9: // 0x43x9: A2AxH
1731
+				return DMA[d].Address >> 8;
1732
+
1733
+			case 0xa: // 0x43xa: NLTRx
1734
+				return DMA[d].LineCount ^ (DMA[d].Repeat ? 0x00 : 0x80);
1735
+
1736
+			case 0xb: // 0x43xb: ????x
1737
+			case 0xf: // 0x43xf: mirror of 0x43xb
1738
+				return DMA[d].UnknownByte;
1739
+
1740
+			default:
1741
+				return OpenBus;
1742
+		}
1743
+	}
1744
+	else
1745
+	{
1746
+		uint8_t	byte;
1747
+
1748
+		switch (Address)
1749
+		{
1750
+			case 0x4210: // RDNMI
1751
+				byte = Memory.FillRAM[0x4210];
1752
+				Memory.FillRAM[0x4210] = Model->_5A22;
1753
+				return (byte & 0x80) | (OpenBus & 0x70) | Model->_5A22;
1754
+
1755
+			case 0x4211: // TIMEUP
1756
+				byte = CPU.IRQLine ? 0x80 : 0;
1757
+				CPU.IRQLine = false;
1758
+				CPU.IRQTransition = false;
1759
+				return byte | (OpenBus & 0x7f);
1760
+
1761
+			case 0x4212: // HVBJOY
1762
+				return REGISTER_4212() | (OpenBus & 0x3e);
1763
+
1764
+			case 0x4213: // RDIO
1765
+				return Memory.FillRAM[0x4213];
1766
+
1767
+			case 0x4214: // RDDIVL
1768
+			case 0x4215: // RDDIVH
1769
+			case 0x4216: // RDMPYL
1770
+			case 0x4217: // RDMPYH
1771
+				return Memory.FillRAM[Address];
1772
+
1773
+			case 0x4218: // JOY1L
1774
+			case 0x4219: // JOY1H
1775
+			case 0x421a: // JOY2L
1776
+			case 0x421b: // JOY2H
1777
+			case 0x421c: // JOY3L
1778
+			case 0x421d: // JOY3H
1779
+			case 0x421e: // JOY4L
1780
+			case 0x421f: // JOY4H
1781
+			#ifdef SNES_JOY_READ_CALLBACKS
1782
+				extern bool pad_read;
1783
+				if (Memory.FillRAM[0x4200] & 1)
1784
+				{
1785
+					S9xOnSNESPadRead();
1786
+					pad_read = true;
1787
+				}
1788
+			#endif
1789
+				return Memory.FillRAM[Address];
1790
+
1791
+			default:
1792
+				/*if (Settings.SPC7110 && Address >= 0x4800)
1793
+					return S9xGetSPC7110(Address);*/
1794
+				if (Settings.SDD1 && Address >= 0x4800 && Address <= 0x4807)
1795
+					return Memory.FillRAM[Address];
1796
+				return OpenBus;
1797
+		}
1798
+	}
1799
+}
1800
+
1801
+void S9xResetPPU()
1802
+{
1803
+	S9xSoftResetPPU();
1804
+	//S9xControlsReset();
1805
+	PPU.M7HOFS = 0;
1806
+	PPU.M7VOFS = 0;
1807
+	PPU.M7byte = 0;
1808
+}
1809
+
1810
+void S9xSoftResetPPU()
1811
+{
1812
+	//S9xControlsSoftReset();
1813
+
1814
+	PPU.VMA.High = 0;
1815
+	PPU.VMA.Increment = 1;
1816
+	PPU.VMA.Address = 0;
1817
+	PPU.VMA.FullGraphicCount = 0;
1818
+	PPU.VMA.Shift = 0;
1819
+
1820
+	PPU.WRAM = 0;
1821
+
1822
+	for (int c = 0; c < 4; c++)
1823
+	{
1824
+		PPU.BG[c].SCBase = 0;
1825
+		PPU.BG[c].HOffset = 0;
1826
+		PPU.BG[c].VOffset = 0;
1827
+		PPU.BG[c].BGSize = 0;
1828
+		PPU.BG[c].NameBase = 0;
1829
+		PPU.BG[c].SCSize = 0;
1830
+	}
1831
+
1832
+	PPU.BGMode = 0;
1833
+	PPU.BG3Priority = 0;
1834
+
1835
+	PPU.CGFLIP = 0;
1836
+	PPU.CGFLIPRead = 0;
1837
+	PPU.CGADD = 0;
1838
+
1839
+	for (int c = 0; c < 256; c++)
1840
+	{
1841
+		IPPU.Red[c]   = (c & 7) << 2;
1842
+		IPPU.Green[c] = ((c >> 3) & 7) << 2;
1843
+		IPPU.Blue[c]  = ((c >> 6) & 2) << 3;
1844
+		PPU.CGDATA[c] = IPPU.Red[c] | (IPPU.Green[c] << 5) | (IPPU.Blue[c] << 10);
1845
+	}
1846
+
1847
+	for (int c = 0; c < 128; c++)
1848
+	{
1849
+		PPU.OBJ[c].HPos = 0;
1850
+		PPU.OBJ[c].VPos = 0;
1851
+		PPU.OBJ[c].HFlip = 0;
1852
+		PPU.OBJ[c].VFlip = 0;
1853
+		PPU.OBJ[c].Name = 0;
1854
+		PPU.OBJ[c].Priority = 0;
1855
+		PPU.OBJ[c].Palette = 0;
1856
+		PPU.OBJ[c].Size = 0;
1857
+	}
1858
+
1859
+	PPU.OBJThroughMain = false;
1860
+	PPU.OBJThroughSub = false;
1861
+	PPU.OBJAddition = false;
1862
+	PPU.OBJNameBase = 0;
1863
+	PPU.OBJNameSelect = 0;
1864
+	PPU.OBJSizeSelect = 0;
1865
+
1866
+	PPU.OAMAddr = 0;
1867
+	PPU.SavedOAMAddr = 0;
1868
+	PPU.OAMPriorityRotation = 0;
1869
+	PPU.OAMFlip = 0;
1870
+	PPU.OAMReadFlip = 0;
1871
+	PPU.OAMTileAddress = 0;
1872
+	PPU.OAMWriteRegister = 0;
1873
+	ZeroMemory(PPU.OAMData, 512 + 32);
1874
+
1875
+	PPU.FirstSprite = 0;
1876
+	PPU.LastSprite = 127;
1877
+	PPU.RangeTimeOver = 0;
1878
+
1879
+	PPU.HTimerEnabled = false;
1880
+	PPU.VTimerEnabled = false;
1881
+	PPU.HTimerPosition = Timings.H_Max + 1;
1882
+	PPU.VTimerPosition = Timings.V_Max + 1;
1883
+	PPU.IRQHBeamPos = 0x1ff;
1884
+	PPU.IRQVBeamPos = 0x1ff;
1885
+
1886
+	PPU.HBeamFlip = 0;
1887
+	PPU.VBeamFlip = 0;
1888
+	PPU.HBeamPosLatched = 0;
1889
+	PPU.VBeamPosLatched = 0;
1890
+	PPU.GunHLatch = 0;
1891
+	PPU.GunVLatch = 1000;
1892
+	PPU.HVBeamCounterLatched = 0;
1893
+
1894
+	PPU.Mode7HFlip = false;
1895
+	PPU.Mode7VFlip = false;
1896
+	PPU.Mode7Repeat = 0;
1897
+	PPU.MatrixA = 0;
1898
+	PPU.MatrixB = 0;
1899
+	PPU.MatrixC = 0;
1900
+	PPU.MatrixD = 0;
1901
+	PPU.CentreX = 0;
1902
+	PPU.CentreY = 0;
1903
+
1904
+	PPU.Mosaic = 0;
1905
+	PPU.BGMosaic[0] = false;
1906
+	PPU.BGMosaic[1] = false;
1907
+	PPU.BGMosaic[2] = false;
1908
+	PPU.BGMosaic[3] = false;
1909
+	
1910
+	PPU.Window1Left = 1;
1911
+	PPU.Window1Right = 0;
1912
+	PPU.Window2Left = 1;
1913
+	PPU.Window2Right = 0;
1914
+	PPU.RecomputeClipWindows = true;
1915
+
1916
+	for (int c = 0; c < 6; c++)
1917
+	{
1918
+		PPU.ClipCounts[c] = 0;
1919
+		PPU.ClipWindowOverlapLogic[c] = CLIP_OR;
1920
+		PPU.ClipWindow1Enable[c] = false;
1921
+		PPU.ClipWindow2Enable[c] = false;
1922
+		PPU.ClipWindow1Inside[c] = true;
1923
+		PPU.ClipWindow2Inside[c] = true;
1924
+	}
1925
+
1926
+	PPU.ForcedBlanking = true;
1927
+
1928
+	PPU.FixedColourRed = 0;
1929
+	PPU.FixedColourGreen = 0;
1930
+	PPU.FixedColourBlue = 0;
1931
+	PPU.Brightness = 0;
1932
+	PPU.ScreenHeight = SNES_HEIGHT;
1933
+
1934
+	PPU.Need16x8Mulitply = false;
1935
+	PPU.BGnxOFSbyte = 0;
1936
+
1937
+	PPU.HDMA = 0;
1938
+	PPU.HDMAEnded = 0;
1939
+
1940
+	PPU.OpenBus1 = 0;
1941
+	PPU.OpenBus2 = 0;
1942
+
1943
+	for (int c = 0; c < 2; c++)
1944
+		memset(&IPPU.Clip[c], 0, sizeof(struct ClipData));
1945
+	IPPU.ColorsChanged = true;
1946
+	IPPU.OBJChanged = true;
1947
+	IPPU.DirectColourMapsNeedRebuild = true;
1948
+	ZeroMemory(IPPU.TileCached[TILE_2BIT], MAX_2BIT_TILES);
1949
+	ZeroMemory(IPPU.TileCached[TILE_4BIT], MAX_4BIT_TILES);
1950
+	ZeroMemory(IPPU.TileCached[TILE_8BIT], MAX_8BIT_TILES);
1951
+	ZeroMemory(IPPU.TileCached[TILE_2BIT_EVEN], MAX_2BIT_TILES);
1952
+	ZeroMemory(IPPU.TileCached[TILE_2BIT_ODD],  MAX_2BIT_TILES);
1953
+	ZeroMemory(IPPU.TileCached[TILE_4BIT_EVEN], MAX_4BIT_TILES);
1954
+	ZeroMemory(IPPU.TileCached[TILE_4BIT_ODD],  MAX_4BIT_TILES);
1955
+	IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better?
1956
+	IPPU.Interlace = false;
1957
+	IPPU.InterlaceOBJ = false;
1958
+	IPPU.DoubleWidthPixels = false;
1959
+	IPPU.DoubleHeightPixels = false;
1960
+	IPPU.CurrentLine = 0;
1961
+	IPPU.PreviousLine = 0;
1962
+	IPPU.XB = NULL;
1963
+	for (int c = 0; c < 256; c++)
1964
+		IPPU.ScreenColors[c] = c;
1965
+	IPPU.MaxBrightness = 0;
1966
+	IPPU.RenderThisFrame = true;
1967
+	IPPU.RenderedScreenWidth = SNES_WIDTH;
1968
+	IPPU.RenderedScreenHeight = SNES_HEIGHT;
1969
+	IPPU.FrameCount = 0;
1970
+	IPPU.RenderedFramesCount = 0;
1971
+	IPPU.DisplayedRenderedFrameCount = 0;
1972
+	IPPU.SkippedFrames = 0;
1973
+	IPPU.FrameSkip = 0;
1974
+
1975
+	//S9xFixColourBrightness();
1976
+
1977
+	for (int c = 0; c < 0x8000; c += 0x100)
1978
+		memset(&Memory.FillRAM[c], c >> 8, 0x100);
1979
+	ZeroMemory(&Memory.FillRAM[0x2100], 0x100);
1980
+	ZeroMemory(&Memory.FillRAM[0x4200], 0x100);
1981
+	ZeroMemory(&Memory.FillRAM[0x4000], 0x100);
1982
+	// For BS Suttehakkun 2...
1983
+	ZeroMemory(&Memory.FillRAM[0x1000], 0x1000);
1984
+
1985
+	Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = 0xff;
1986
+}