Browse code

fix mingw build, clean up new warnings

Adam Higerd authored on 2021/02/11 17:42:05
Showing 1 changed files
... ...
@@ -1,4 +1,5 @@
1 1
 #include <algorithm>
2
+#include <string.h>
2 3
 #include "GBA.h"
3 4
 #include "GBAcpu.h"
4 5
 #include "GBAinline.h"
Browse code

* Small Makefile changes.

* Removed a couple files that were not being used.
* Cleanups found with clang's -Weverything (and shutting it up about a
lot of things that were ridiculous, as well as ignoring some of the
warnings still coming up).

Naram Qashat authored on 2014/09/25 12:28:21
Showing 1 changed files
... ...
@@ -31,36 +31,36 @@ uint32_t cpuPrefetch[2];
31 31
 
32 32
 int cpuTotalTicks = 0;
33 33
 
34
-int lcdTicks = 208;
35
-uint8_t timerOnOffDelay = 0;
36
-uint16_t timer0Value = 0;
34
+static int lcdTicks = 208;
35
+static uint8_t timerOnOffDelay = 0;
36
+static uint16_t timer0Value = 0;
37 37
 bool timer0On = false;
38 38
 int timer0Ticks = 0;
39
-int timer0Reload = 0;
39
+static int timer0Reload = 0;
40 40
 int timer0ClockReload  = 0;
41
-uint16_t timer1Value = 0;
41
+static uint16_t timer1Value = 0;
42 42
 bool timer1On = false;
43 43
 int timer1Ticks = 0;
44
-int timer1Reload = 0;
44
+static int timer1Reload = 0;
45 45
 int timer1ClockReload  = 0;
46
-uint16_t timer2Value = 0;
46
+static uint16_t timer2Value = 0;
47 47
 bool timer2On = false;
48 48
 int timer2Ticks = 0;
49
-int timer2Reload = 0;
49
+static int timer2Reload = 0;
50 50
 int timer2ClockReload  = 0;
51
-uint16_t timer3Value = 0;
51
+static uint16_t timer3Value = 0;
52 52
 bool timer3On = false;
53 53
 int timer3Ticks = 0;
54
-int timer3Reload = 0;
54
+static int timer3Reload = 0;
55 55
 int timer3ClockReload  = 0;
56
-uint32_t dma0Source = 0;
57
-uint32_t dma0Dest = 0;
58
-uint32_t dma1Source = 0;
59
-uint32_t dma1Dest = 0;
60
-uint32_t dma2Source = 0;
61
-uint32_t dma2Dest = 0;
62
-uint32_t dma3Source = 0;
63
-uint32_t dma3Dest = 0;
56
+static uint32_t dma0Source = 0;
57
+static uint32_t dma0Dest = 0;
58
+static uint32_t dma1Source = 0;
59
+static uint32_t dma1Dest = 0;
60
+static uint32_t dma2Source = 0;
61
+static uint32_t dma2Dest = 0;
62
+static uint32_t dma3Source = 0;
63
+static uint32_t dma3Dest = 0;
64 64
 
65 65
 static const int TIMER_TICKS[] = { 0, 6, 8, 10 };
66 66
 
... ...
@@ -83,14 +83,13 @@ uint8_t memoryWaitSeq32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 }
83 83
 //const u8 videoMemoryWait[16] =
84 84
 //  {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
85 85
 
86
-
87 86
 uint8_t biosProtected[4];
88 87
 
89 88
 #ifdef WORDS_BIGENDIAN
90
-bool cpuBiosSwapped = false;
89
+static bool cpuBiosSwapped = false;
91 90
 #endif
92 91
 
93
-uint32_t myROM[] =
92
+static uint32_t myROM[] =
94 93
 {
95 94
 	0xEA000006,
96 95
 	0xEA000093,
Browse code

Use std::copy_n/std::fill_n instead of std::copy/std::fill where possible.

Naram Qashat authored on 2014/09/08 16:52:49
Showing 1 changed files
... ...
@@ -1505,7 +1505,7 @@ void CPUInit()
1505 1505
 		cpuBitsSet[i] = count;
1506 1506
 	}
1507 1507
 
1508
-	std::fill(&ioReadable[0], &ioReadable[0x304], true);
1508
+	std::fill_n(&ioReadable[0], 0x304, true);
1509 1509
 	std::fill(&ioReadable[0x10], &ioReadable[0x48], false);
1510 1510
 	std::fill(&ioReadable[0x4c], &ioReadable[0x50], false);
1511 1511
 	std::fill(&ioReadable[0x54], &ioReadable[0x60], false);
Browse code

Updating the VBA-M code to revision 1231.

Naram Qashat authored on 2014/09/08 12:20:28
Showing 1 changed files
... ...
@@ -1,6 +1,4 @@
1 1
 #include <algorithm>
2
-#include <cstdlib>
3
-#include <cstring>
4 2
 #include "GBA.h"
5 3
 #include "GBAcpu.h"
6 4
 #include "GBAinline.h"
... ...
@@ -19,7 +17,8 @@ bool busPrefetch = false;
19 17
 bool busPrefetchEnable = false;
20 18
 uint32_t busPrefetchCount = 0;
21 19
 static int cpuDmaTicksToUpdate = 0;
22
-static uint32_t cpuDmaLast = 0;
20
+bool cpuDmaHack = false;
21
+uint32_t cpuDmaLast = 0;
23 22
 static int dummyAddress = 0;
24 23
 
25 24
 int cpuNextEvent = 0;
... ...
@@ -27,7 +26,6 @@ int cpuNextEvent = 0;
27 26
 static bool intState = false;
28 27
 bool stopState = false;
29 28
 bool holdState = false;
30
-int holdType = 0;
31 29
 
32 30
 uint32_t cpuPrefetch[2];
33 31
 
... ...
@@ -63,8 +61,6 @@ uint32_t dma2Source = 0;
63 61
 uint32_t dma2Dest = 0;
64 62
 uint32_t dma3Source = 0;
65 63
 uint32_t dma3Dest = 0;
66
-char buffer[1024];
67
-int count = 0;
68 64
 
69 65
 static const int TIMER_TICKS[] = { 0, 6, 8, 10 };
70 66
 
... ...
@@ -80,6 +76,14 @@ uint8_t memoryWait32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
80 76
 uint8_t memoryWaitSeq[] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
81 77
 uint8_t memoryWaitSeq32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
82 78
 
79
+// The videoMemoryWait constants are used to add some waitstates
80
+// if the opcode access video memory data outside of vblank/hblank
81
+// It seems to happen on only one ticks for each pixel.
82
+// Not used for now (too problematic with current code).
83
+//const u8 videoMemoryWait[16] =
84
+//  {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
85
+
86
+
83 87
 uint8_t biosProtected[4];
84 88
 
85 89
 #ifdef WORDS_BIGENDIAN
... ...
@@ -294,17 +298,18 @@ int CPULoadRom()
294 298
 {
295 299
 	romSize = 0x2000000;
296 300
 
301
+	memset(&rom[0], 0, 0x2000000);
297 302
 	memset(&workRAM[0], 0, 0x40000);
298 303
 
299 304
 	if (cpuIsMultiBoot)
300
-		mapgsf(workRAM, 0x40000, romSize);
305
+		mapgsf(&workRAM[0], 0x40000, romSize);
301 306
 	else
302
-		mapgsf(rom, 0x2000000, romSize);
307
+		mapgsf(&rom[0], 0x2000000, romSize);
303 308
 
304
-	uint16_t *temp = reinterpret_cast<uint16_t *>(rom + ((romSize + 1) & ~1));
309
+	auto temp = reinterpret_cast<uint16_t *>(&rom[(romSize + 1) & ~1]);
305 310
 	for (int i = (romSize + 1) & ~1; i < 0x2000000; i += 2)
306 311
 	{
307
-		WRITE16LE(temp, (i >> 1) & 0xFFFF);
312
+		WRITE16LE(&temp[0], (i >> 1) & 0xFFFF);
308 313
 		++temp;
309 314
 	}
310 315
 
... ...
@@ -353,6 +358,9 @@ void CPUUpdateFlags(bool breakLoop)
353 358
 
354 359
 void CPUSwitchMode(int mode, bool saveState, bool breakLoop)
355 360
 {
361
+	//if(armMode == mode)
362
+	//	return;
363
+
356 364
 	CPUUpdateCPSR();
357 365
 
358 366
 	switch (armMode)
... ...
@@ -505,7 +513,6 @@ void CPUSoftwareInterrupt(int comment)
505 513
 			break;
506 514
 		case 0x02:
507 515
 			holdState = true;
508
-			holdType = -1;
509 516
 			cpuNextEvent = cpuTotalTicks;
510 517
 			break;
511 518
 		case 0x03:
... ...
@@ -526,41 +533,41 @@ void CPUSoftwareInterrupt(int comment)
526 533
 			BIOS_ArcTan2();
527 534
 			break;
528 535
 		case 0x0B:
529
-		{
530
-			int len = (reg[2].I & 0x1FFFFF) >> 1;
531
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
532 536
 			{
533
-				if ((reg[2].I >> 24) & 1)
537
+				int len = (reg[2].I & 0x1FFFFF) >> 1;
538
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
534 539
 				{
535
-					if ((reg[2].I >> 26) & 1)
536
-						SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1);
537
-					else
538
-						SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
539
-				}
540
-				else
541
-				{
542
-					if ((reg[2].I >> 26) & 1)
543
-						SWITicks = (10 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1);
540
+					if ((reg[2].I >> 24) & 1)
541
+					{
542
+						if ((reg[2].I >> 26) & 1)
543
+							SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1);
544
+						else
545
+							SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
546
+					}
544 547
 					else
545
-						SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
548
+					{
549
+						if ((reg[2].I >> 26) & 1)
550
+							SWITicks = (10 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1);
551
+						else
552
+							SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
553
+					}
546 554
 				}
547 555
 			}
548 556
 			BIOS_CpuSet();
549 557
 			break;
550
-		}
551 558
 		case 0x0C:
552
-		{
553
-			int len = (reg[2].I & 0x1FFFFF) >> 5;
554
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
555 559
 			{
556
-				if ((reg[2].I >> 24) & 1)
557
-					SWITicks = (6 + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 1)) * len;
558
-				else
559
-					SWITicks = (9 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[0].I >> 24) & 0xF] + memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 2)) * len;
560
+				int len = (reg[2].I & 0x1FFFFF) >> 5;
561
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
562
+				{
563
+					if ((reg[2].I >> 24) & 1)
564
+						SWITicks = (6 + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 1)) * len;
565
+					else
566
+						SWITicks = (9 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[0].I >> 24) & 0xF] + memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 2)) * len;
567
+				}
560 568
 			}
561 569
 			BIOS_CpuFastSet();
562 570
 			break;
563
-		}
564 571
 		case 0x0D:
565 572
 			BIOS_GetBiosChecksum();
566 573
 			break;
... ...
@@ -571,77 +578,77 @@ void CPUSoftwareInterrupt(int comment)
571 578
 			BIOS_ObjAffineSet();
572 579
 			break;
573 580
 		case 0x10:
574
-		{
575
-			int len = CPUReadHalfWord(reg[2].I);
576
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
577
-				SWITicks = (32 + memoryWait[(reg[0].I >> 24) & 0xF]) * len;
581
+			{
582
+				int len = CPUReadHalfWord(reg[2].I);
583
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
584
+					SWITicks = (32 + memoryWait[(reg[0].I >> 24) & 0xF]) * len;
585
+			}
578 586
 			BIOS_BitUnPack();
579 587
 			break;
580
-		}
581 588
 		case 0x11:
582
-		{
583
-			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
584
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
585
-				SWITicks = (9 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
589
+			{
590
+				uint32_t len = CPUReadMemory(reg[0].I) >> 8;
591
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
592
+					SWITicks = (9 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
593
+			}
586 594
 			BIOS_LZ77UnCompWram();
587 595
 			break;
588
-		}
589 596
 		case 0x12:
590
-		{
591
-			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
592
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
593
-				SWITicks = (19 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
597
+			{
598
+				uint32_t len = CPUReadMemory(reg[0].I) >> 8;
599
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
600
+					SWITicks = (19 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
601
+			}
594 602
 			BIOS_LZ77UnCompVram();
595 603
 			break;
596
-		}
597 604
 		case 0x13:
598
-		{
599
-			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
600
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
601
-				SWITicks = (29 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1)) * len;
605
+			{
606
+				uint32_t len = CPUReadMemory(reg[0].I) >> 8;
607
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
608
+					SWITicks = (29 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1)) * len;
609
+			}
602 610
 			BIOS_HuffUnComp();
603 611
 			break;
604
-		}
605 612
 		case 0x14:
606
-		{
607
-			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
608
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
609
-				SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
613
+			{
614
+				uint32_t len = CPUReadMemory(reg[0].I) >> 8;
615
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
616
+					SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
617
+			}
610 618
 			BIOS_RLUnCompWram();
611 619
 			break;
612
-		}
613 620
 		case 0x15:
614
-		{
615
-			uint32_t len = CPUReadMemory(reg[0].I) >> 9;
616
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
617
-				SWITicks = (34 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
621
+			{
622
+				uint32_t len = CPUReadMemory(reg[0].I) >> 9;
623
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
624
+					SWITicks = (34 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
625
+			}
618 626
 			BIOS_RLUnCompVram();
619 627
 			break;
620
-		}
621 628
 		case 0x16:
622
-		{
623
-			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
624
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
625
-				SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
629
+			{
630
+				uint32_t len = CPUReadMemory(reg[0].I) >> 8;
631
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
632
+					SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
633
+			}
626 634
 			BIOS_Diff8bitUnFilterWram();
627 635
 			break;
628
-		}
629 636
 		case 0x17:
630
-		{
631
-			uint32_t len = CPUReadMemory(reg[0].I) >> 9;
632
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
633
-				SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
637
+			{
638
+				uint32_t len = CPUReadMemory(reg[0].I) >> 9;
639
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
640
+					SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
641
+			}
634 642
 			BIOS_Diff8bitUnFilterVram();
635 643
 			break;
636
-		}
637 644
 		case 0x18:
638
-		{
639
-			uint32_t len = CPUReadMemory(reg[0].I) >> 9;
640
-			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
641
-				SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
645
+			{
646
+				uint32_t len = CPUReadMemory(reg[0].I) >> 9;
647
+				if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
648
+					SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
649
+			}
642 650
 			BIOS_Diff16bitUnFilter();
643 651
 			break;
644
-		}
645 652
 		case 0x19:
646 653
 			if (reg[0].I)
647 654
 				soundPause();
... ...
@@ -657,7 +664,7 @@ void CPUSoftwareInterrupt(int comment)
657 664
 	}
658 665
 }
659 666
 
660
-void CPUCompareVCOUNT()
667
+static void CPUCompareVCOUNT()
661 668
 {
662 669
 	if (VCOUNT == (DISPSTAT >> 8))
663 670
 	{
... ...
@@ -683,7 +690,7 @@ void CPUCompareVCOUNT()
683 690
 	}
684 691
 }
685 692
 
686
-void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int transfer32)
693
+static void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int transfer32)
687 694
 {
688 695
 	int sm = s >> 24;
689 696
 	int dm = d >> 24;
... ...
@@ -691,12 +698,16 @@ void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int t
691 698
 	int dw = 0;
692 699
 	int sc = c;
693 700
 
701
+	cpuDmaHack = true;
694 702
 	// This is done to get the correct waitstates.
695 703
 	if (sm > 15)
696 704
 		sm = 15;
697 705
 	if (dm > 15)
698 706
 		dm = 15;
699 707
 
708
+	//if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07))
709
+	//    blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ?  true : false);
710
+
700 711
 	if (transfer32)
701 712
 	{
702 713
 		s &= 0xFFFFFFFC;
... ...
@@ -765,185 +776,174 @@ void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int t
765 776
 	}
766 777
 
767 778
 	cpuDmaTicksToUpdate += totalTicks;
779
+	cpuDmaHack = false;
768 780
 }
769 781
 
770 782
 void CPUCheckDMA(int reason, int dmamask)
771 783
 {
772 784
 	// DMA 0
773
-	if ((DM0CNT_H & 0x8000) && (dmamask & 1))
785
+	if ((DM0CNT_H & 0x8000) && (dmamask & 1) && ((DM0CNT_H >> 12) & 3) == reason)
774 786
 	{
775
-		if (((DM0CNT_H >> 12) & 3) == reason)
787
+		uint32_t sourceIncrement = 4;
788
+		uint32_t destIncrement = 4;
789
+		switch ((DM0CNT_H >> 7) & 3)
776 790
 		{
777
-			uint32_t sourceIncrement = 4;
778
-			uint32_t destIncrement = 4;
779
-			switch ((DM0CNT_H >> 7) & 3)
780
-			{
781
-				case 1:
782
-					sourceIncrement = static_cast<uint32_t>(-4);
783
-					break;
784
-				case 2:
785
-					sourceIncrement = 0;
786
-			}
787
-			switch ((DM0CNT_H >> 5) & 3)
788
-			{
789
-				case 1:
790
-					destIncrement = static_cast<uint32_t>(-4);
791
-					break;
792
-				case 2:
793
-					destIncrement = 0;
794
-			}
795
-			doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, DM0CNT_L ? DM0CNT_L : 0x4000, DM0CNT_H & 0x0400);
791
+			case 1:
792
+				sourceIncrement = static_cast<uint32_t>(-4);
793
+				break;
794
+			case 2:
795
+				sourceIncrement = 0;
796
+		}
797
+		switch ((DM0CNT_H >> 5) & 3)
798
+		{
799
+			case 1:
800
+				destIncrement = static_cast<uint32_t>(-4);
801
+				break;
802
+			case 2:
803
+				destIncrement = 0;
804
+		}
805
+		doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, DM0CNT_L ? DM0CNT_L : 0x4000, DM0CNT_H & 0x0400);
796 806
 
797
-			if (DM0CNT_H & 0x4000)
798
-			{
799
-				IF |= 0x0100;
800
-				UPDATE_REG(0x202, IF);
801
-				cpuNextEvent = cpuTotalTicks;
802
-			}
807
+		if (DM0CNT_H & 0x4000)
808
+		{
809
+			IF |= 0x0100;
810
+			UPDATE_REG(0x202, IF);
811
+			cpuNextEvent = cpuTotalTicks;
812
+		}
803 813
 
804
-			if (((DM0CNT_H >> 5) & 3) == 3)
805
-				dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
814
+		if (((DM0CNT_H >> 5) & 3) == 3)
815
+			dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
806 816
 
807
-			if (!(DM0CNT_H & 0x0200) || !reason)
808
-			{
809
-				DM0CNT_H &= 0x7FFF;
810
-				UPDATE_REG(0xBA, DM0CNT_H);
811
-			}
817
+		if (!(DM0CNT_H & 0x0200) || !reason)
818
+		{
819
+			DM0CNT_H &= 0x7FFF;
820
+			UPDATE_REG(0xBA, DM0CNT_H);
812 821
 		}
813 822
 	}
814 823
 
815 824
 	// DMA 1
816
-	if ((DM1CNT_H & 0x8000) && (dmamask & 2))
825
+	if ((DM1CNT_H & 0x8000) && (dmamask & 2) && ((DM1CNT_H >> 12) & 3) == reason)
817 826
 	{
818
-		if (((DM1CNT_H >> 12) & 3) == reason)
827
+		uint32_t sourceIncrement = 4;
828
+		uint32_t destIncrement = 4;
829
+		switch ((DM1CNT_H >> 7) & 3)
819 830
 		{
820
-			uint32_t sourceIncrement = 4;
821
-			uint32_t destIncrement = 4;
822
-			switch ((DM1CNT_H >> 7) & 3)
823
-			{
824
-				case 1:
825
-					sourceIncrement = static_cast<uint32_t>(-4);
826
-					break;
827
-				case 2:
828
-					sourceIncrement = 0;
829
-			}
830
-			switch ((DM1CNT_H >> 5) & 3)
831
-			{
832
-				case 1:
833
-					destIncrement = static_cast<uint32_t>(-4);
834
-					break;
835
-				case 2:
836
-					destIncrement = 0;
837
-			}
838
-			if (reason == 3)
839
-				doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, 0x0400);
840
-			else
841
-				doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, DM1CNT_L ? DM1CNT_L : 0x4000, DM1CNT_H & 0x0400);
831
+			case 1:
832
+				sourceIncrement = static_cast<uint32_t>(-4);
833
+				break;
834
+			case 2:
835
+				sourceIncrement = 0;
836
+		}
837
+		switch ((DM1CNT_H >> 5) & 3)
838
+		{
839
+			case 1:
840
+				destIncrement = static_cast<uint32_t>(-4);
841
+				break;
842
+			case 2:
843
+				destIncrement = 0;
844
+		}
845
+		if (reason == 3)
846
+			doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, 0x0400);
847
+		else
848
+			doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, DM1CNT_L ? DM1CNT_L : 0x4000, DM1CNT_H & 0x0400);
842 849
 
843
-			if (DM1CNT_H & 0x4000)
844
-			{
845
-				IF |= 0x0200;
846
-				UPDATE_REG(0x202, IF);
847
-				cpuNextEvent = cpuTotalTicks;
848
-			}
850
+		if (DM1CNT_H & 0x4000)
851
+		{
852
+			IF |= 0x0200;
853
+			UPDATE_REG(0x202, IF);
854
+			cpuNextEvent = cpuTotalTicks;
855
+		}
849 856
 
850
-			if (((DM1CNT_H >> 5) & 3) == 3)
851
-				dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
857
+		if (((DM1CNT_H >> 5) & 3) == 3)
858
+			dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
852 859
 
853
-			if (!(DM1CNT_H & 0x0200) || !reason)
854
-			{
855
-				DM1CNT_H &= 0x7FFF;
856
-				UPDATE_REG(0xC6, DM1CNT_H);
857
-			}
860
+		if (!(DM1CNT_H & 0x0200) || !reason)
861
+		{
862
+			DM1CNT_H &= 0x7FFF;
863
+			UPDATE_REG(0xC6, DM1CNT_H);
858 864
 		}
859 865
 	}
860 866
 
861 867
 	// DMA 2
862
-	if ((DM2CNT_H & 0x8000) && (dmamask & 4))
868
+	if ((DM2CNT_H & 0x8000) && (dmamask & 4) && ((DM2CNT_H >> 12) & 3) == reason)
863 869
 	{
864
-		if (((DM2CNT_H >> 12) & 3) == reason)
870
+		uint32_t sourceIncrement = 4;
871
+		uint32_t destIncrement = 4;
872
+		switch ((DM2CNT_H >> 7) & 3)
865 873
 		{
866
-			uint32_t sourceIncrement = 4;
867
-			uint32_t destIncrement = 4;
868
-			switch ((DM2CNT_H >> 7) & 3)
869
-			{
870
-				case 1:
871
-					sourceIncrement = static_cast<uint32_t>(-4);
872
-					break;
873
-				case 2:
874
-					sourceIncrement = 0;
875
-			}
876
-			switch ((DM2CNT_H >> 5) & 3)
877
-			{
878
-				case 1:
879
-					destIncrement = static_cast<uint32_t>(-4);
880
-					break;
881
-				case 2:
882
-					destIncrement = 0;
883
-			}
884
-			if (reason == 3)
885
-				doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, 0x0400);
886
-			else
887
-				doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, DM2CNT_L ? DM2CNT_L : 0x4000, DM2CNT_H & 0x0400);
874
+			case 1:
875
+				sourceIncrement = static_cast<uint32_t>(-4);
876
+				break;
877
+			case 2:
878
+				sourceIncrement = 0;
879
+		}
880
+		switch ((DM2CNT_H >> 5) & 3)
881
+		{
882
+			case 1:
883
+				destIncrement = static_cast<uint32_t>(-4);
884
+				break;
885
+			case 2:
886
+				destIncrement = 0;
887
+		}
888
+		if (reason == 3)
889
+			doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, 0x0400);
890
+		else
891
+			doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, DM2CNT_L ? DM2CNT_L : 0x4000, DM2CNT_H & 0x0400);
888 892
 
889
-			if (DM2CNT_H & 0x4000)
890
-			{
891
-				IF |= 0x0400;
892
-				UPDATE_REG(0x202, IF);
893
-				cpuNextEvent = cpuTotalTicks;
894
-			}
893
+		if (DM2CNT_H & 0x4000)
894
+		{
895
+			IF |= 0x0400;
896
+			UPDATE_REG(0x202, IF);
897
+			cpuNextEvent = cpuTotalTicks;
898
+		}
895 899
 
896
-			if (((DM2CNT_H >> 5) & 3) == 3)
897
-				dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
900
+		if (((DM2CNT_H >> 5) & 3) == 3)
901
+			dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
898 902
 
899
-			if (!(DM2CNT_H & 0x0200) || !reason)
900
-			{
901
-				DM2CNT_H &= 0x7FFF;
902
-				UPDATE_REG(0xD2, DM2CNT_H);
903
-			}
903
+		if (!(DM2CNT_H & 0x0200) || !reason)
904
+		{
905
+			DM2CNT_H &= 0x7FFF;
906
+			UPDATE_REG(0xD2, DM2CNT_H);
904 907
 		}
905 908
 	}
906 909
 
907 910
 	// DMA 3
908
-	if ((DM3CNT_H & 0x8000) && (dmamask & 8))
911
+	if ((DM3CNT_H & 0x8000) && (dmamask & 8) && ((DM3CNT_H >> 12) & 3) == reason)
909 912
 	{
910
-		if (((DM3CNT_H >> 12) & 3) == reason)
913
+		uint32_t sourceIncrement = 4;
914
+		uint32_t destIncrement = 4;
915
+		switch ((DM3CNT_H >> 7) & 3)
911 916
 		{
912
-			uint32_t sourceIncrement = 4;
913
-			uint32_t destIncrement = 4;
914
-			switch ((DM3CNT_H >> 7) & 3)
915
-			{
916
-				case 1:
917
-					sourceIncrement = static_cast<uint32_t>(-4);
918
-					break;
919
-				case 2:
920
-					sourceIncrement = 0;
921
-			}
922
-			switch ((DM3CNT_H >> 5) & 3)
923
-			{
924
-				case 1:
925
-					destIncrement = static_cast<uint32_t>(-4);
926
-					break;
927
-				case 2:
928
-					destIncrement = 0;
929
-			}
930
-			doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, DM3CNT_L ? DM3CNT_L : 0x10000, DM3CNT_H & 0x0400);
931
-			
932
-			if (DM3CNT_H & 0x4000)
933
-			{
934
-				IF |= 0x0800;
935
-				UPDATE_REG(0x202, IF);
936
-				cpuNextEvent = cpuTotalTicks;
937
-			}
917
+			case 1:
918
+				sourceIncrement = static_cast<uint32_t>(-4);
919
+				break;
920
+			case 2:
921
+				sourceIncrement = 0;
922
+		}
923
+		switch ((DM3CNT_H >> 5) & 3)
924
+		{
925
+			case 1:
926
+				destIncrement = static_cast<uint32_t>(-4);
927
+				break;
928
+			case 2:
929
+				destIncrement = 0;
930
+		}
931
+		doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, DM3CNT_L ? DM3CNT_L : 0x10000, DM3CNT_H & 0x0400);
938 932
 
939
-			if (((DM3CNT_H >> 5) & 3) == 3)
940
-				dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
933
+		if (DM3CNT_H & 0x4000)
934
+		{
935
+			IF |= 0x0800;
936
+			UPDATE_REG(0x202, IF);
937
+			cpuNextEvent = cpuTotalTicks;
938
+		}
941 939
 
942
-			if (!(DM3CNT_H & 0x0200) || !reason)
943
-			{
944
-				DM3CNT_H &= 0x7FFF;
945
-				UPDATE_REG(0xDE, DM3CNT_H);
946
-			}
940
+		if (((DM3CNT_H >> 5) & 3) == 3)
941
+			dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
942
+
943
+		if (!(DM3CNT_H & 0x0200) || !reason)
944
+		{
945
+			DM3CNT_H &= 0x7FFF;
946
+			UPDATE_REG(0xDE, DM3CNT_H);
947 947
 		}
948 948
 	}
949 949
 }
... ...
@@ -953,41 +953,41 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
953 953
 	switch (address)
954 954
 	{
955 955
 		case 0x00:
956
-		{
957
-			if ((value & 7) > 5)
958
-				// display modes above 0-5 are prohibited
959
-				DISPCNT = value & 7;
960
-			bool change = !!((DISPCNT ^ value) & 0x80);
961
-			uint16_t changeBGon = (~DISPCNT & value) & 0x0F00; // these layers are being activated
956
+			{
957
+				if ((value & 7) > 5)
958
+					// display modes above 0-5 are prohibited
959
+					DISPCNT = value & 7;
960
+				bool change = !!((DISPCNT ^ value) & 0x80);
961
+				uint16_t changeBGon = (~DISPCNT & value) & 0x0F00; // these layers are being activated
962 962
 
963
-			DISPCNT = value & 0xFFF7; // bit 3 can only be accessed by the BIOS to enable GBC mode
964
-			UPDATE_REG(0x00, DISPCNT);
963
+				DISPCNT = value & 0xFFF7; // bit 3 can only be accessed by the BIOS to enable GBC mode
964
+				UPDATE_REG(0x00, DISPCNT);
965 965
 
966
-			if (changeBGon)
967
-			{
968
-				layerEnableDelay = 4;
969
-				layerEnable = layerSettings & value & ~changeBGon;
970
-			}
971
-			else
972
-			{
973
-				layerEnable = layerSettings & value;
974
-				//CPUUpdateTicks();
975
-			}
966
+				if (changeBGon)
967
+				{
968
+					layerEnableDelay = 4;
969
+					layerEnable = layerSettings & value & ~changeBGon;
970
+				}
971
+				else
972
+				{
973
+					layerEnable = layerSettings & value;
974
+					// CPUUpdateTicks();
975
+				}
976 976
 
977
-			if (change && !(value & 0x80))
978
-			{
979
-				if (!(DISPSTAT & 1))
977
+				if (change && !(value & 0x80))
980 978
 				{
981
-					lcdTicks = 1008;
982
-					//VCOUNT = 0;
983
-					//UPDATE_REG(0x06, VCOUNT);
984
-					DISPSTAT &= 0xFFFC;
985
-					UPDATE_REG(0x04, DISPSTAT);
986
-					CPUCompareVCOUNT();
979
+					if (!(DISPSTAT & 1))
980
+					{
981
+						//lcdTicks = 1008;
982
+						//VCOUNT = 0;
983
+						//UPDATE_REG(0x06, VCOUNT);
984
+						DISPSTAT &= 0xFFFC;
985
+						UPDATE_REG(0x04, DISPSTAT);
986
+						CPUCompareVCOUNT();
987
+					}
987 988
 				}
988 989
 			}
989 990
 			break;
990
-		}
991 991
 		case 0x04:
992 992
 			DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7);
993 993
 			UPDATE_REG(0x04, DISPSTAT);
... ...
@@ -1199,21 +1199,21 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
1199 1199
 			UPDATE_REG(0xB8, 0);
1200 1200
 			break;
1201 1201
 		case 0xBA:
1202
-		{
1203
-			bool start = !!((DM0CNT_H ^ value) & 0x8000);
1204
-			value &= 0xF7E0;
1202
+			{
1203
+				bool start = !!((DM0CNT_H ^ value) & 0x8000);
1204
+				value &= 0xF7E0;
1205 1205
 
1206
-			DM0CNT_H = value;
1207
-			UPDATE_REG(0xBA, DM0CNT_H);
1206
+				DM0CNT_H = value;
1207
+				UPDATE_REG(0xBA, DM0CNT_H);
1208 1208
 
1209
-			if (start && (value & 0x8000))
1210
-			{
1211
-				dma0Source = DM0SAD_L | (DM0SAD_H << 16);
1212
-				dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
1213
-				CPUCheckDMA(0, 1);
1209
+				if (start && (value & 0x8000))
1210
+				{
1211
+					dma0Source = DM0SAD_L | (DM0SAD_H << 16);
1212
+					dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
1213
+					CPUCheckDMA(0, 1);
1214
+				}
1214 1215
 			}
1215 1216
 			break;
1216
-		}
1217 1217
 		case 0xBC:
1218 1218
 			DM1SAD_L = value;
1219 1219
 			UPDATE_REG(0xBC, DM1SAD_L);
... ...
@@ -1235,21 +1235,21 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
1235 1235
 			UPDATE_REG(0xC4, 0);
1236 1236
 			break;
1237 1237
 		case 0xC6:
1238
-		{
1239
-			bool start = !!((DM1CNT_H ^ value) & 0x8000);
1240
-			value &= 0xF7E0;
1238
+			{
1239
+				bool start = !!((DM1CNT_H ^ value) & 0x8000);
1240
+				value &= 0xF7E0;
1241 1241
 
1242
-			DM1CNT_H = value;
1243
-			UPDATE_REG(0xC6, DM1CNT_H);
1242
+				DM1CNT_H = value;
1243
+				UPDATE_REG(0xC6, DM1CNT_H);
1244 1244
 
1245
-			if (start && (value & 0x8000))
1246
-			{
1247
-				dma1Source = DM1SAD_L | (DM1SAD_H << 16);
1248
-				dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
1249
-				CPUCheckDMA(0, 2);
1245
+				if (start && (value & 0x8000))
1246
+				{
1247
+					dma1Source = DM1SAD_L | (DM1SAD_H << 16);
1248
+					dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
1249
+					CPUCheckDMA(0, 2);
1250
+				}
1250 1251
 			}
1251 1252
 			break;
1252
-		}
1253 1253
 		case 0xC8:
1254 1254
 			DM2SAD_L = value;
1255 1255
 			UPDATE_REG(0xC8, DM2SAD_L);
... ...
@@ -1271,21 +1271,21 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
1271 1271
 			UPDATE_REG(0xD0, 0);
1272 1272
 			break;
1273 1273
 		case 0xD2:
1274
-		{
1275
-			bool start = !!((DM2CNT_H ^ value) & 0x8000);
1276
-			value &= 0xF7E0;
1274
+			{
1275
+				bool start = !!((DM2CNT_H ^ value) & 0x8000);
1276
+				value &= 0xF7E0;
1277 1277
 
1278
-			DM2CNT_H = value;
1279
-			UPDATE_REG(0xD2, DM2CNT_H);
1278
+				DM2CNT_H = value;
1279
+				UPDATE_REG(0xD2, DM2CNT_H);
1280 1280
 
1281
-			if (start && (value & 0x8000))
1282
-			{
1283
-				dma2Source = DM2SAD_L | (DM2SAD_H << 16);
1284
-				dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
1285
-				CPUCheckDMA(0, 4);
1281
+				if (start && (value & 0x8000))
1282
+				{
1283
+					dma2Source = DM2SAD_L | (DM2SAD_H << 16);
1284
+					dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
1285
+					CPUCheckDMA(0, 4);
1286
+				}
1286 1287
 			}
1287 1288
 			break;
1288
-		}
1289 1289
 		case 0xD4:
1290 1290
 			DM3SAD_L = value;
1291 1291
 			UPDATE_REG(0xD4, DM3SAD_L);
... ...
@@ -1307,21 +1307,21 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
1307 1307
 			UPDATE_REG(0xDC, 0);
1308 1308
 			break;
1309 1309
 		case 0xDE:
1310
-		{
1311
-			bool start = !!((DM3CNT_H ^ value) & 0x8000);
1312
-			value &= 0xFFE0;
1310
+			{
1311
+				bool start = !!((DM3CNT_H ^ value) & 0x8000);
1312
+				value &= 0xFFE0;
1313 1313
 
1314
-			DM3CNT_H = value;
1315
-			UPDATE_REG(0xDE, DM3CNT_H);
1314
+				DM3CNT_H = value;
1315
+				UPDATE_REG(0xDE, DM3CNT_H);
1316 1316
 
1317
-			if (start && (value & 0x8000))
1318
-			{
1319
-				dma3Source = DM3SAD_L | (DM3SAD_H << 16);
1320
-				dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
1321
-				CPUCheckDMA(0, 8);
1317
+				if (start && (value & 0x8000))
1318
+				{
1319
+					dma3Source = DM3SAD_L | (DM3SAD_H << 16);
1320
+					dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
1321
+					CPUCheckDMA(0, 8);
1322
+				}
1322 1323
 			}
1323 1324
 			break;
1324
-		}
1325 1325
 		case 0x100:
1326 1326
 			timer0Reload = value;
1327 1327
 			break;
... ...
@@ -1396,7 +1396,6 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
1396 1396
 			busPrefetch = false;
1397 1397
 			busPrefetchCount = 0;
1398 1398
 			UPDATE_REG(0x204, value & 0x7FFF);
1399
-
1400 1399
 			break;
1401 1400
 		case 0x208:
1402 1401
 			IME = value & 1;
... ...
@@ -1414,7 +1413,7 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
1414 1413
 	}
1415 1414
 }
1416 1415
 
1417
-void applyTimer()
1416
+static void applyTimer()
1418 1417
 {
1419 1418
 	if (timerOnOffDelay & 1)
1420 1419
 	{
... ...
@@ -1478,7 +1477,6 @@ void applyTimer()
1478 1477
 }
1479 1478
 
1480 1479
 uint8_t cpuBitsSet[256];
1481
-uint8_t cpuLowestBitSet[256];
1482 1480
 
1483 1481
 void CPUInit()
1484 1482
 {
... ...
@@ -1491,7 +1489,7 @@ void CPUInit()
1491 1489
 	}
1492 1490
 #endif
1493 1491
 
1494
-	memcpy(&bios[0], &myROM[0], sizeof(myROM));
1492
+	memcpy(&bios[0], myROM, sizeof(myROM));
1495 1493
 
1496 1494
 	biosProtected[0] = 0x00;
1497 1495
 	biosProtected[1] = 0xf0;
... ...
@@ -1501,16 +1499,10 @@ void CPUInit()
1501 1499
 	for (int i = 0; i < 256; ++i)
1502 1500
 	{
1503 1501
 		int count = 0;
1504
-		int j;
1505
-		for (j = 0; j < 8; ++j)
1502
+		for (int j = 0; j < 8; ++j)
1506 1503
 			if (i & (1 << j))
1507 1504
 				++count;
1508 1505
 		cpuBitsSet[i] = count;
1509
-
1510
-		for (j = 0; j < 8; ++j)
1511
-			if (i & (1 << j))
1512
-				break;
1513
-		cpuLowestBitSet[i] = j;
1514 1506
 	}
1515 1507
 
1516 1508
 	std::fill(&ioReadable[0], &ioReadable[0x304], true);
... ...
@@ -1658,7 +1650,6 @@ void CPUReset()
1658 1650
 
1659 1651
 	// reset internal state
1660 1652
 	holdState = false;
1661
-	holdType = 0;
1662 1653
 
1663 1654
 	biosProtected[0] = 0x00;
1664 1655
 	biosProtected[1] = 0xf0;
... ...
@@ -1728,10 +1719,12 @@ void CPUReset()
1728 1719
 
1729 1720
 	ARM_PREFETCH();
1730 1721
 
1722
+	cpuDmaHack = false;
1723
+
1731 1724
 	SWITicks = 0;
1732 1725
 }
1733 1726
 
1734
-void CPUInterrupt()
1727
+static void CPUInterrupt()
1735 1728
 {
1736 1729
 	uint32_t PC = reg[15].I;
1737 1730
 	bool savedState = armState;
... ...
@@ -1747,7 +1740,7 @@ void CPUInterrupt()
1747 1740
 	reg[15].I += 4;
1748 1741
 	ARM_PREFETCH();
1749 1742
 
1750
-	//if(!holdState)
1743
+	//if (!holdState)
1751 1744
 	biosProtected[0] = 0x02;
1752 1745
 	biosProtected[1] = 0xc0;
1753 1746
 	biosProtected[2] = 0x5e;
... ...
@@ -1801,7 +1794,6 @@ void CPULoop(int ticks)
1801 1794
 			cpuTotalTicks = 0;
1802 1795
 
1803 1796
 		updateLoop:
1804
-
1805 1797
 			if (IRQTicks)
1806 1798
 			{
1807 1799
 				IRQTicks -= clockTicks;
... ...
@@ -1837,7 +1829,7 @@ void CPULoop(int ticks)
1837 1829
 						}
1838 1830
 					}
1839 1831
 
1840
-					if (VCOUNT >= 228) //Reaching last line
1832
+					if (VCOUNT > 227) //Reaching last line
1841 1833
 					{
1842 1834
 						DISPSTAT &= 0xFFFC;
1843 1835
 						UPDATE_REG(0x04, DISPSTAT);
... ...
@@ -1858,10 +1850,6 @@ void CPULoop(int ticks)
1858 1850
 						DISPSTAT &= 0xFFFD;
1859 1851
 						if (VCOUNT == 160)
1860 1852
 						{
1861
-							++count;
1862
-							if (count == 60)
1863
-								count = 0;
1864
-
1865 1853
 							DISPSTAT |= 1;
1866 1854
 							DISPSTAT &= 0xFFFD;
1867 1855
 							UPDATE_REG(0x04, DISPSTAT);
... ...
@@ -2070,7 +2058,6 @@ void CPULoop(int ticks)
2070 2058
 							intState = false;
2071 2059
 							holdState = false;
2072 2060
 							stopState = false;
2073
-							holdType = 0;
2074 2061
 						}
2075 2062
 					}
2076 2063
 					else
... ...
@@ -2087,7 +2074,6 @@ void CPULoop(int ticks)
2087 2074
 							CPUInterrupt();
2088 2075
 							holdState = false;
2089 2076
 							stopState = false;
2090
-							holdType = 0;
2091 2077
 						}
2092 2078
 					}
2093 2079
 
Browse code

[GSF] Some more code cleanup, also removed a few files that were unneeded.

Naram Qashat authored on 2013/05/16 01:25:34
Showing 1 changed files
... ...
@@ -11,10 +11,6 @@
11 11
 
12 12
 extern int mapgsf(uint8_t *a, int l, int &s);
13 13
 
14
-#ifdef __GNUC__
15
-#define _stricmp strcasecmp
16
-#endif
17
-
18 14
 int SWITicks = 0;
19 15
 static int IRQTicks = 0;
20 16
 
... ...
@@ -306,8 +302,7 @@ int CPULoadRom()
306 302
 		mapgsf(rom, 0x2000000, romSize);
307 303
 
308 304
 	uint16_t *temp = reinterpret_cast<uint16_t *>(rom + ((romSize + 1) & ~1));
309
-	int i;
310
-	for (i = (romSize + 1) & ~1; i < 0x2000000; i += 2)
305
+	for (int i = (romSize + 1) & ~1; i < 0x2000000; i += 2)
311 306
 	{
312 307
 		WRITE16LE(temp, (i >> 1) & 0xFFFF);
313 308
 		++temp;
... ...
@@ -498,9 +493,6 @@ void CPUSoftwareInterrupt(int comment)
498 493
 		comment >>= 16;
499 494
 	if (comment == 0xfa)
500 495
 		return;
501
-	// This would be correct, but it causes problems if uncommented
502
-	//else
503
-		//biosProtected = 0xe3a02004;
504 496
 
505 497
 	switch (comment)
506 498
 	{
... ...
@@ -543,7 +535,7 @@ void CPUSoftwareInterrupt(int comment)
543 535
 					if ((reg[2].I >> 26) & 1)
544 536
 						SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1);
545 537
 					else
546
-						SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * (len);
538
+						SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
547 539
 				}
548 540
 				else
549 541
 				{
... ...
@@ -638,7 +630,7 @@ void CPUSoftwareInterrupt(int comment)
638 630
 		{
639 631
 			uint32_t len = CPUReadMemory(reg[0].I) >> 9;
640 632
 			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
641
-				SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF]<<1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
633
+				SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
642 634
 			BIOS_Diff8bitUnFilterVram();
643 635
 			break;
644 636
 		}
... ...
@@ -786,8 +778,6 @@ void CPUCheckDMA(int reason, int dmamask)
786 778
 			uint32_t destIncrement = 4;
787 779
 			switch ((DM0CNT_H >> 7) & 3)
788 780
 			{
789
-				case 0:
790
-					break;
791 781
 				case 1:
792 782
 					sourceIncrement = static_cast<uint32_t>(-4);
793 783
 					break;
... ...
@@ -796,8 +786,6 @@ void CPUCheckDMA(int reason, int dmamask)
796 786
 			}
797 787
 			switch ((DM0CNT_H >> 5) & 3)
798 788
 			{
799
-				case 0:
800
-					break;
801 789
 				case 1:
802 790
 					destIncrement = static_cast<uint32_t>(-4);
803 791
 					break;
... ...
@@ -833,8 +821,6 @@ void CPUCheckDMA(int reason, int dmamask)
833 821
 			uint32_t destIncrement = 4;
834 822
 			switch ((DM1CNT_H >> 7) & 3)
835 823
 			{
836
-				case 0:
837
-					break;
838 824
 				case 1:
839 825
 					sourceIncrement = static_cast<uint32_t>(-4);
840 826
 					break;
... ...
@@ -843,8 +829,6 @@ void CPUCheckDMA(int reason, int dmamask)
843 829
 			}
844 830
 			switch ((DM1CNT_H >> 5) & 3)
845 831
 			{
846
-				case 0:
847
-					break;
848 832
 				case 1:
849 833
 					destIncrement = static_cast<uint32_t>(-4);
850 834
 					break;
... ...
@@ -883,8 +867,6 @@ void CPUCheckDMA(int reason, int dmamask)
883 867
 			uint32_t destIncrement = 4;
884 868
 			switch ((DM2CNT_H >> 7) & 3)
885 869
 			{
886
-				case 0:
887
-					break;
888 870
 				case 1:
889 871
 					sourceIncrement = static_cast<uint32_t>(-4);
890 872
 					break;
... ...
@@ -893,8 +875,6 @@ void CPUCheckDMA(int reason, int dmamask)
893 875
 			}
894 876
 			switch ((DM2CNT_H >> 5) & 3)
895 877
 			{
896
-				case 0:
897
-					break;
898 878
 				case 1:
899 879
 					destIncrement = static_cast<uint32_t>(-4);
900 880
 					break;
... ...
@@ -933,8 +913,6 @@ void CPUCheckDMA(int reason, int dmamask)
933 913
 			uint32_t destIncrement = 4;
934 914
 			switch ((DM3CNT_H >> 7) & 3)
935 915
 			{
936
-				case 0:
937
-					break;
938 916
 				case 1:
939 917
 					sourceIncrement = static_cast<uint32_t>(-4);
940 918
 					break;
... ...
@@ -943,8 +921,6 @@ void CPUCheckDMA(int reason, int dmamask)
943 921
 			}
944 922
 			switch ((DM3CNT_H >> 5) & 3)
945 923
 			{
946
-				case 0:
947
-					break;
948 924
 				case 1:
949 925
 					destIncrement = static_cast<uint32_t>(-4);
950 926
 					break;
... ...
@@ -952,6 +928,7 @@ void CPUCheckDMA(int reason, int dmamask)
952 928
 					destIncrement = 0;
953 929
 			}
954 930
 			doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, DM3CNT_L ? DM3CNT_L : 0x10000, DM3CNT_H & 0x0400);
931
+			
955 932
 			if (DM3CNT_H & 0x4000)
956 933
 			{
957 934
 				IF |= 0x0800;
... ...
@@ -1002,6 +979,8 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
1002 979
 				if (!(DISPSTAT & 1))
1003 980
 				{
1004 981
 					lcdTicks = 1008;
982
+					//VCOUNT = 0;
983
+					//UPDATE_REG(0x06, VCOUNT);
1005 984
 					DISPSTAT &= 0xFFFC;
1006 985
 					UPDATE_REG(0x04, DISPSTAT);
1007 986
 					CPUCompareVCOUNT();
... ...
@@ -1085,7 +1064,7 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
1085 1064
 			UPDATE_REG(0x28, BG2X_L);
1086 1065
 			break;
1087 1066
 		case 0x2A:
1088
-			BG2X_H = (value & 0xFFF);
1067
+			BG2X_H = value & 0xFFF;
1089 1068
 			UPDATE_REG(0x2A, BG2X_H);
1090 1069
 			break;
1091 1070
 		case 0x2C:
... ...
@@ -1476,7 +1455,7 @@ void applyTimer()
1476 1455
 			timer2Ticks = (0x10000 - TM2D) << timer2ClockReload;
1477 1456
 			UPDATE_REG(0x108, TM2D);
1478 1457
 		}
1479
-		timer2On = !(timer2Value & 0x80);
1458
+		timer2On = !!(timer2Value & 0x80);
1480 1459
 		TM2CNT = timer2Value & 0xC7;
1481 1460
 		UPDATE_REG(0x10A, TM2CNT);
1482 1461
 	}
... ...
@@ -1511,7 +1490,8 @@ void CPUInit()
1511 1490
 		cpuBiosSwapped = true;
1512 1491
 	}
1513 1492
 #endif
1514
-	memcpy(&bios[0], myROM, sizeof(myROM));
1493
+
1494
+	memcpy(&bios[0], &myROM[0], sizeof(myROM));
1515 1495
 
1516 1496
 	biosProtected[0] = 0x00;
1517 1497
 	biosProtected[1] = 0xf0;
... ...
@@ -1724,7 +1704,7 @@ void CPUReset()
1724 1704
 	map[2].mask = 0x3FFFF;
1725 1705
 	map[3].address = &internalRAM[0];
1726 1706
 	map[3].mask = 0x7FFF;
1727
-	map[4].address = ioMem;
1707
+	map[4].address = &ioMem[0];
1728 1708
 	map[4].mask = 0x3FF;
1729 1709
 	map[5].address = &paletteRAM[0];
1730 1710
 	map[5].mask = 0x3FF;
Browse code

[GSF] Massive code cleanup.

(As an aside, blargg's code style makes me go blarg myself.)

Naram Qashat authored on 2013/05/14 01:07:18
Showing 1 changed files
... ...
@@ -1,84 +1,43 @@
1
-#include <stdio.h>
2
-#include <stdlib.h>
3
-#include <memory.h>
4
-#include <stdarg.h>
5
-#include <string.h>
1
+#include <algorithm>
2
+#include <cstdlib>
3
+#include <cstring>
6 4
 #include "GBA.h"
7 5
 #include "GBAcpu.h"
8 6
 #include "GBAinline.h"
9 7
 #include "Globals.h"
10
-//#include "GBAGfx.h"
11
-//#include "EEprom.h"
12
-//#include "Flash.h"
13 8
 #include "Sound.h"
14
-//#include "Sram.h"
15 9
 #include "bios.h"
16
-//#include "Cheats.h"
17
-//#include "../NLS.h"
18
-//#include "elf.h"
19
-//#include "../Util.h"
20 10
 #include "../common/Port.h"
21
-//#include "../System.h"
22
-//#include "agbprint.h"
23
-//#include "GBALink.h"
24 11
 
25
-extern int mapgsf(uint8_t* a, int l, int &s);
26
-
27
-#ifdef PROFILING
28
-#include "prof/prof.h"
29
-#endif
12
+extern int mapgsf(uint8_t *a, int l, int &s);
30 13
 
31 14
 #ifdef __GNUC__
32 15
 #define _stricmp strcasecmp
33 16
 #endif
34 17
 
35
-extern int emulating;
36
-
37 18
 int SWITicks = 0;
38
-int IRQTicks = 0;
19
+static int IRQTicks = 0;
39 20
 
40
-uint32_t mastercode = 0;
41
-int layerEnableDelay = 0;
21
+static int layerEnableDelay = 0;
42 22
 bool busPrefetch = false;
43 23
 bool busPrefetchEnable = false;
44 24
 uint32_t busPrefetchCount = 0;
45
-int cpuDmaTicksToUpdate = 0;
46
-int cpuDmaCount = 0;
47
-uint32_t cpuDmaLast = 0;
48
-int dummyAddress = 0;
25
+static int cpuDmaTicksToUpdate = 0;
26
+static uint32_t cpuDmaLast = 0;
27
+static int dummyAddress = 0;
49 28
 
50
-bool cpuBreakLoop = false;
51 29
 int cpuNextEvent = 0;
52 30
 
53
-int gbaSaveType = 0; // used to remember the save type on reset
54
-bool intState = false;
31
+static bool intState = false;
55 32
 bool stopState = false;
56 33
 bool holdState = false;
57 34
 int holdType = 0;
58
-bool cpuSramEnabled = true;
59
-bool cpuFlashEnabled = true;
60
-bool cpuEEPROMEnabled = true;
61
-bool cpuEEPROMSensorEnabled = false;
62 35
 
63 36
 uint32_t cpuPrefetch[2];
64 37
 
65 38
 int cpuTotalTicks = 0;
66
-#ifdef PROFILING
67
-int profilingTicks = 0;
68
-int profilingTicksReload = 0;
69
-static profile_segment *profilSegment = NULL;
70
-#endif
71 39
 
72
-#ifdef BKPT_SUPPORT
73
-uint8_t freezeWorkRAM[0x40000];
74
-uint8_t freezeInternalRAM[0x8000];
75
-uint8_t freezeVRAM[0x18000];
76
-uint8_t freezePRAM[0x400];
77
-uint8_t freezeOAM[0x400];
78
-bool debugger_last;
79
-#endif
80
-
81
-int lcdTicks = (useBios && !skipBios) ? 1008 : 208;
40
+int lcdTicks = 208;
82 41
 uint8_t timerOnOffDelay = 0;
83 42
 uint16_t timer0Value = 0;
84 43
 bool timer0On = false;
... ...
@@ -108,52 +67,22 @@ uint32_t dma2Source = 0;
108 67
 uint32_t dma2Dest = 0;
109 68
 uint32_t dma3Source = 0;
110 69
 uint32_t dma3Dest = 0;
111
-//void (*cpuSaveGameFunc)(u32,u8) = /*flashSaveDecide*/0;
112
-//void (*renderLine)() = /*mode0RenderLine*/0;
113
-bool fxOn = false;
114
-bool windowOn = false;
115
-int frameCount = 0;
116 70
 char buffer[1024];
117
-uint32_t lastTime = 0;
118 71
 int count = 0;
119 72
 
120
-int capture = 0;
121
-int capturePrevious = 0;
122
-int captureNumber = 0;
123
-
124
-const int TIMER_TICKS[4] = {
125
-  0,
126
-  6,
127
-  8,
128
-  10
129
-};
73
+static const int TIMER_TICKS[] = { 0, 6, 8, 10 };
130 74
 
131
-const uint32_t  objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
132
-const uint8_t gamepakRamWaitState[4] = { 4, 3, 2, 8 };
133
-const uint8_t gamepakWaitState[4] =  { 4, 3, 2, 8 };
134
-const uint8_t gamepakWaitState0[2] = { 2, 1 };
135
-const uint8_t gamepakWaitState1[2] = { 4, 1 };
136
-const uint8_t gamepakWaitState2[2] = { 8, 1 };
137
-const bool isInRom [16]=
138
-  { false, false, false, false, false, false, false, false,
139
-    true, true, true, true, true, true, false, false };
140
-
141
-uint8_t memoryWait[16] =
142
-  { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
143
-uint8_t memoryWait32[16] =
144
-  { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
145
-uint8_t memoryWaitSeq[16] =
146
-  { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
147
-uint8_t memoryWaitSeq32[16] =
148
-  { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
149
-
150
-// The videoMemoryWait constants are used to add some waitstates
151
-// if the opcode access video memory data outside of vblank/hblank
152
-// It seems to happen on only one ticks for each pixel.
153
-// Not used for now (too problematic with current code).
154
-//const u8 videoMemoryWait[16] =
155
-//  {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
75
+const uint32_t objTilesAddress[] = { 0x010000, 0x014000, 0x014000 };
76
+static const uint8_t gamepakRamWaitState[] = { 4, 3, 2, 8 };
77
+static const uint8_t gamepakWaitState[] =  { 4, 3, 2, 8 };
78
+static const uint8_t gamepakWaitState0[] = { 2, 1 };
79
+static const uint8_t gamepakWaitState1[] = { 4, 1 };
80
+static const uint8_t gamepakWaitState2[] = { 8, 1 };
156 81
 
82
+uint8_t memoryWait[] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
83
+uint8_t memoryWait32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
84
+uint8_t memoryWaitSeq[] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
85
+uint8_t memoryWaitSeq32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
157 86
 
158 87
 uint8_t biosProtected[4];
159 88
 
... ...
@@ -161,3857 +90,2054 @@ uint8_t biosProtected[4];
161 90
 bool cpuBiosSwapped = false;
162 91
 #endif
163 92
 
164
-uint32_t myROM[] = {
165
-0xEA000006,
166
-0xEA000093,
167
-0xEA000006,
168
-0x00000000,
169
-0x00000000,
170
-0x00000000,
171
-0xEA000088,
172
-0x00000000,
173
-0xE3A00302,
174
-0xE1A0F000,
175
-0xE92D5800,
176
-0xE55EC002,
177
-0xE28FB03C,
178
-0xE79BC10C,
179
-0xE14FB000,
180
-0xE92D0800,
181
-0xE20BB080,
182
-0xE38BB01F,
183
-0xE129F00B,
184
-0xE92D4004,
185
-0xE1A0E00F,
186
-0xE12FFF1C,
187
-0xE8BD4004,
188
-0xE3A0C0D3,
189
-0xE129F00C,
190
-0xE8BD0800,
191
-0xE169F00B,
192
-0xE8BD5800,
193
-0xE1B0F00E,
194
-0x0000009C,
195
-0x0000009C,
196
-0x0000009C,
197
-0x0000009C,
198
-0x000001F8,
199
-0x000001F0,
200
-0x000000AC,
201
-0x000000A0,
202
-0x000000FC,
203
-0x00000168,
204
-0xE12FFF1E,
205
-0xE1A03000,
206
-0xE1A00001,
207
-0xE1A01003,
208
-0xE2113102,
209
-0x42611000,
210
-0xE033C040,
211
-0x22600000,
212
-0xE1B02001,
213
-0xE15200A0,
214
-0x91A02082,
215
-0x3AFFFFFC,
216
-0xE1500002,
217
-0xE0A33003,
218
-0x20400002,
219
-0xE1320001,
220
-0x11A020A2,
221
-0x1AFFFFF9,
222
-0xE1A01000,
223
-0xE1A00003,
224
-0xE1B0C08C,
225
-0x22600000,
226
-0x42611000,
227
-0xE12FFF1E,
228
-0xE92D0010,
229
-0xE1A0C000,
230
-0xE3A01001,
231
-0xE1500001,
232
-0x81A000A0,
233
-0x81A01081,
234
-0x8AFFFFFB,
235
-0xE1A0000C,
236
-0xE1A04001,
237
-0xE3A03000,
238
-0xE1A02001,
239
-0xE15200A0,
240
-0x91A02082,
241
-0x3AFFFFFC,
242
-0xE1500002,
243
-0xE0A33003,
244
-0x20400002,
245
-0xE1320001,
246
-0x11A020A2,
247
-0x1AFFFFF9,
248
-0xE0811003,
249
-0xE1B010A1,
250
-0xE1510004,
251
-0x3AFFFFEE,
252
-0xE1A00004,
253
-0xE8BD0010,
254
-0xE12FFF1E,
255
-0xE0010090,
256
-0xE1A01741,
257
-0xE2611000,
258
-0xE3A030A9,
259
-0xE0030391,
260
-0xE1A03743,
261
-0xE2833E39,
262
-0xE0030391,
263
-0xE1A03743,
264
-0xE2833C09,
265
-0xE283301C,
266
-0xE0030391,
267
-0xE1A03743,
268
-0xE2833C0F,
269
-0xE28330B6,
270
-0xE0030391,
271
-0xE1A03743,
272
-0xE2833C16,
273
-0xE28330AA,
274
-0xE0030391,
275
-0xE1A03743,
276
-0xE2833A02,
277
-0xE2833081,
278
-0xE0030391,
279
-0xE1A03743,
280
-0xE2833C36,
281
-0xE2833051,
282
-0xE0030391,
283
-0xE1A03743,
284
-0xE2833CA2,
285
-0xE28330F9,
286
-0xE0000093,
287
-0xE1A00840,
288
-0xE12FFF1E,
289
-0xE3A00001,
290
-0xE3A01001,
291
-0xE92D4010,
292
-0xE3A03000,
293
-0xE3A04001,
294
-0xE3500000,
295
-0x1B000004,
296
-0xE5CC3301,
297
-0xEB000002,
298
-0x0AFFFFFC,
299
-0xE8BD4010,
300
-0xE12FFF1E,
301
-0xE3A0C301,
302
-0xE5CC3208,
303
-0xE15C20B8,
304
-0xE0110002,
305
-0x10222000,
306
-0x114C20B8,
307
-0xE5CC4208,
308
-0xE12FFF1E,
309
-0xE92D500F,
310
-0xE3A00301,
311
-0xE1A0E00F,
312
-0xE510F004,
313
-0xE8BD500F,
314
-0xE25EF004,
315
-0xE59FD044,
316
-0xE92D5000,
317
-0xE14FC000,
318
-0xE10FE000,
319
-0xE92D5000,
320
-0xE3A0C302,
321
-0xE5DCE09C,
322
-0xE35E00A5,
323
-0x1A000004,
324
-0x05DCE0B4,
325
-0x021EE080,
326
-0xE28FE004,
327
-0x159FF018,
328
-0x059FF018,
329
-0xE59FD018,
330
-0xE8BD5000,
331
-0xE169F00C,
332
-0xE8BD5000,
333
-0xE25EF004,
334
-0x03007FF0,
335
-0x09FE2000,
336
-0x09FFC000,
337
-0x03007FE0
93
+uint32_t myROM[] =
94
+{
95
+	0xEA000006,
96
+	0xEA000093,
97
+	0xEA000006,
98
+	0x00000000,
99
+	0x00000000,
100
+	0x00000000,
101
+	0xEA000088,
102
+	0x00000000,
103
+	0xE3A00302,
104
+	0xE1A0F000,
105
+	0xE92D5800,
106
+	0xE55EC002,
107
+	0xE28FB03C,
108
+	0xE79BC10C,
109
+	0xE14FB000,
110
+	0xE92D0800,
111
+	0xE20BB080,
112
+	0xE38BB01F,
113
+	0xE129F00B,
114
+	0xE92D4004,
115
+	0xE1A0E00F,
116
+	0xE12FFF1C,
117
+	0xE8BD4004,
118
+	0xE3A0C0D3,
119
+	0xE129F00C,
120
+	0xE8BD0800,
121
+	0xE169F00B,
122
+	0xE8BD5800,
123
+	0xE1B0F00E,
124
+	0x0000009C,
125
+	0x0000009C,
126
+	0x0000009C,
127
+	0x0000009C,
128
+	0x000001F8,
129
+	0x000001F0,
130
+	0x000000AC,
131
+	0x000000A0,
132
+	0x000000FC,
133
+	0x00000168,
134
+	0xE12FFF1E,
135
+	0xE1A03000,
136
+	0xE1A00001,
137
+	0xE1A01003,
138
+	0xE2113102,
139
+	0x42611000,
140
+	0xE033C040,
141
+	0x22600000,
142
+	0xE1B02001,
143
+	0xE15200A0,
144
+	0x91A02082,
145
+	0x3AFFFFFC,
146
+	0xE1500002,
147
+	0xE0A33003,
148
+	0x20400002,
149
+	0xE1320001,
150
+	0x11A020A2,
151
+	0x1AFFFFF9,
152
+	0xE1A01000,
153
+	0xE1A00003,
154
+	0xE1B0C08C,
155
+	0x22600000,
156
+	0x42611000,
157
+	0xE12FFF1E,
158
+	0xE92D0010,
159
+	0xE1A0C000,
160
+	0xE3A01001,
161
+	0xE1500001,
162
+	0x81A000A0,
163
+	0x81A01081,
164
+	0x8AFFFFFB,
165
+	0xE1A0000C,
166
+	0xE1A04001,
167
+	0xE3A03000,
168
+	0xE1A02001,
169
+	0xE15200A0,
170
+	0x91A02082,
171
+	0x3AFFFFFC,
172
+	0xE1500002,
173
+	0xE0A33003,
174
+	0x20400002,
175
+	0xE1320001,
176
+	0x11A020A2,
177
+	0x1AFFFFF9,
178
+	0xE0811003,
179
+	0xE1B010A1,
180
+	0xE1510004,
181
+	0x3AFFFFEE,
182
+	0xE1A00004,
183
+	0xE8BD0010,
184
+	0xE12FFF1E,
185
+	0xE0010090,
186
+	0xE1A01741,
187
+	0xE2611000,
188
+	0xE3A030A9,
189
+	0xE0030391,
190
+	0xE1A03743,
191
+	0xE2833E39,
192
+	0xE0030391,
193
+	0xE1A03743,
194
+	0xE2833C09,
195
+	0xE283301C,
196
+	0xE0030391,
197
+	0xE1A03743,
198
+	0xE2833C0F,
199
+	0xE28330B6,
200
+	0xE0030391,
201
+	0xE1A03743,
202
+	0xE2833C16,
203
+	0xE28330AA,
204
+	0xE0030391,
205
+	0xE1A03743,
206
+	0xE2833A02,
207
+	0xE2833081,
208
+	0xE0030391,
209
+	0xE1A03743,
210
+	0xE2833C36,
211
+	0xE2833051,
212
+	0xE0030391,
213
+	0xE1A03743,
214
+	0xE2833CA2,
215
+	0xE28330F9,
216
+	0xE0000093,
217
+	0xE1A00840,
218
+	0xE12FFF1E,
219
+	0xE3A00001,
220
+	0xE3A01001,
221
+	0xE92D4010,
222
+	0xE3A03000,
223
+	0xE3A04001,
224
+	0xE3500000,
225
+	0x1B000004,
226
+	0xE5CC3301,
227
+	0xEB000002,
228
+	0x0AFFFFFC,
229
+	0xE8BD4010,
230
+	0xE12FFF1E,
231
+	0xE3A0C301,
232
+	0xE5CC3208,
233
+	0xE15C20B8,
234
+	0xE0110002,
235
+	0x10222000,
236
+	0x114C20B8,
237
+	0xE5CC4208,
238
+	0xE12FFF1E,
239
+	0xE92D500F,
240
+	0xE3A00301,
241
+	0xE1A0E00F,
242
+	0xE510F004,
243
+	0xE8BD500F,
244
+	0xE25EF004,
245
+	0xE59FD044,
246
+	0xE92D5000,
247
+	0xE14FC000,
248
+	0xE10FE000,
249
+	0xE92D5000,
250
+	0xE3A0C302,
251
+	0xE5DCE09C,
252
+	0xE35E00A5,
253
+	0x1A000004,
254
+	0x05DCE0B4,
255
+	0x021EE080,
256
+	0xE28FE004,
257
+	0x159FF018,
258
+	0x059FF018,
259
+	0xE59FD018,
260
+	0xE8BD5000,
261
+	0xE169F00C,
262
+	0xE8BD5000,
263
+	0xE25EF004,
264
+	0x03007FF0,
265
+	0x09FE2000,
266
+	0x09FFC000,
267
+	0x03007FE0
338 268
 };
339 269
 
340
-/*variable_desc saveGameStruct[] = {
341
-  { &DISPCNT  , sizeof(u16) },
342
-  { &DISPSTAT , sizeof(u16) },
343
-  { &VCOUNT   , sizeof(u16) },
344
-  { &BG0CNT   , sizeof(u16) },
345
-  { &BG1CNT   , sizeof(u16) },
346
-  { &BG2CNT   , sizeof(u16) },
347
-  { &BG3CNT   , sizeof(u16) },
348
-  { &BG0HOFS  , sizeof(u16) },
349
-  { &BG0VOFS  , sizeof(u16) },
350
-  { &BG1HOFS  , sizeof(u16) },
351
-  { &BG1VOFS  , sizeof(u16) },
352
-  { &BG2HOFS  , sizeof(u16) },
353
-  { &BG2VOFS  , sizeof(u16) },
354
-  { &BG3HOFS  , sizeof(u16) },
355
-  { &BG3VOFS  , sizeof(u16) },
356
-  { &BG2PA    , sizeof(u16) },
357
-  { &BG2PB    , sizeof(u16) },
358
-  { &BG2PC    , sizeof(u16) },
359
-  { &BG2PD    , sizeof(u16) },
360
-  { &BG2X_L   , sizeof(u16) },
361
-  { &BG2X_H   , sizeof(u16) },
362
-  { &BG2Y_L   , sizeof(u16) },
363
-  { &BG2Y_H   , sizeof(u16) },
364
-  { &BG3PA    , sizeof(u16) },
365
-  { &BG3PB    , sizeof(u16) },
366
-  { &BG3PC    , sizeof(u16) },
367
-  { &BG3PD    , sizeof(u16) },
368
-  { &BG3X_L   , sizeof(u16) },
369
-  { &BG3X_H   , sizeof(u16) },
370
-  { &BG3Y_L   , sizeof(u16) },
371
-  { &BG3Y_H   , sizeof(u16) },
372
-  { &WIN0H    , sizeof(u16) },
373
-  { &WIN1H    , sizeof(u16) },
374
-  { &WIN0V    , sizeof(u16) },
375
-  { &WIN1V    , sizeof(u16) },
376
-  { &WININ    , sizeof(u16) },
377
-  { &WINOUT   , sizeof(u16) },
378
-  { &MOSAIC   , sizeof(u16) },
379
-  { &BLDMOD   , sizeof(u16) },
380
-  { &COLEV    , sizeof(u16) },
381
-  { &COLY     , sizeof(u16) },
382
-  { &DM0SAD_L , sizeof(u16) },
383
-  { &DM0SAD_H , sizeof(u16) },
384
-  { &DM0DAD_L , sizeof(u16) },
385
-  { &DM0DAD_H , sizeof(u16) },
386
-  { &DM0CNT_L , sizeof(u16) },
387
-  { &DM0CNT_H , sizeof(u16) },
388
-  { &DM1SAD_L , sizeof(u16) },
389
-  { &DM1SAD_H , sizeof(u16) },
390
-  { &DM1DAD_L , sizeof(u16) },
391
-  { &DM1DAD_H , sizeof(u16) },
392
-  { &DM1CNT_L , sizeof(u16) },
393
-  { &DM1CNT_H , sizeof(u16) },
394
-  { &DM2SAD_L , sizeof(u16) },
395
-  { &DM2SAD_H , sizeof(u16) },
396
-  { &DM2DAD_L , sizeof(u16) },
397
-  { &DM2DAD_H , sizeof(u16) },
398
-  { &DM2CNT_L , sizeof(u16) },
399
-  { &DM2CNT_H , sizeof(u16) },
400
-  { &DM3SAD_L , sizeof(u16) },
401
-  { &DM3SAD_H , sizeof(u16) },
402
-  { &DM3DAD_L , sizeof(u16) },
403
-  { &DM3DAD_H , sizeof(u16) },
404
-  { &DM3CNT_L , sizeof(u16) },
405
-  { &DM3CNT_H , sizeof(u16) },
406
-  { &TM0D     , sizeof(u16) },
407
-  { &TM0CNT   , sizeof(u16) },
408
-  { &TM1D     , sizeof(u16) },
409
-  { &TM1CNT   , sizeof(u16) },
410
-  { &TM2D     , sizeof(u16) },
411
-  { &TM2CNT   , sizeof(u16) },
412
-  { &TM3D     , sizeof(u16) },
413
-  { &TM3CNT   , sizeof(u16) },
414
-  { &P1       , sizeof(u16) },
415
-  { &IE       , sizeof(u16) },
416
-  { &IF       , sizeof(u16) },
417
-  { &IME      , sizeof(u16) },
418
-  { &holdState, sizeof(bool) },
419
-  { &holdType, sizeof(int) },
420
-  { &lcdTicks, sizeof(int) },
421
-  { &timer0On , sizeof(bool) },
422
-  { &timer0Ticks , sizeof(int) },
423
-  { &timer0Reload , sizeof(int) },
424
-  { &timer0ClockReload  , sizeof(int) },
425
-  { &timer1On , sizeof(bool) },
426
-  { &timer1Ticks , sizeof(int) },
427
-  { &timer1Reload , sizeof(int) },
428
-  { &timer1ClockReload  , sizeof(int) },
429
-  { &timer2On , sizeof(bool) },
430
-  { &timer2Ticks , sizeof(int) },
431
-  { &timer2Reload , sizeof(int) },
432
-  { &timer2ClockReload  , sizeof(int) },
433
-  { &timer3On , sizeof(bool) },
434
-  { &timer3Ticks , sizeof(int) },
435
-  { &timer3Reload , sizeof(int) },
436
-  { &timer3ClockReload  , sizeof(int) },
437
-  { &dma0Source , sizeof(u32) },
438
-  { &dma0Dest , sizeof(u32) },
439
-  { &dma1Source , sizeof(u32) },
440
-  { &dma1Dest , sizeof(u32) },
441
-  { &dma2Source , sizeof(u32) },
442
-  { &dma2Dest , sizeof(u32) },
443
-  { &dma3Source , sizeof(u32) },
444
-  { &dma3Dest , sizeof(u32) },
445
-  { &fxOn, sizeof(bool) },
446
-  { &windowOn, sizeof(bool) },
447
-  { &N_FLAG , sizeof(bool) },
448
-  { &C_FLAG , sizeof(bool) },
449
-  { &Z_FLAG , sizeof(bool) },
450
-  { &V_FLAG , sizeof(bool) },
451
-  { &armState , sizeof(bool) },
452
-  { &armIrqEnable , sizeof(bool) },
453
-  { &armNextPC , sizeof(u32) },
454
-  { &armMode , sizeof(int) },
455
-  { &saveType , sizeof(int) },
456
-  { NULL, 0 }
457
-};*/
458
-
459 270
 static int romSize = 0x2000000;
460 271
 
461
-#ifdef PROFILING
462
-void cpuProfil(profile_segment *seg)
463
-{
464
-    profilSegment = seg;
465
-}
466
-
467
-void cpuEnableProfiling(int hz)
468
-{
469
-  if(hz == 0)
470
-    hz = 100;
471
-  profilingTicks = profilingTicksReload = 16777216 / hz;
472
-  profSetHertz(hz);
473
-}
474
-#endif
475
-
476
-
477
-inline int CPUUpdateTicks()
478
-{
479
-  int cpuLoopTicks = lcdTicks;
480
-
481
-  if(soundTicks < cpuLoopTicks)
482
-    cpuLoopTicks = soundTicks;
483
-
484
-  if(timer0On && (timer0Ticks < cpuLoopTicks)) {
485
-    cpuLoopTicks = timer0Ticks;
486
-  }
487
-  if(timer1On && !(TM1CNT & 4) && (timer1Ticks < cpuLoopTicks)) {
488
-    cpuLoopTicks = timer1Ticks;
489
-  }
490
-  if(timer2On && !(TM2CNT & 4) && (timer2Ticks < cpuLoopTicks)) {
491
-    cpuLoopTicks = timer2Ticks;
492
-  }
493
-  if(timer3On && !(TM3CNT & 4) && (timer3Ticks < cpuLoopTicks)) {
494
-    cpuLoopTicks = timer3Ticks;
495
-  }
496
-#ifdef PROFILING
497
-  if(profilingTicksReload != 0) {
498
-    if(profilingTicks < cpuLoopTicks) {
499
-      cpuLoopTicks = profilingTicks;
500
-    }
501
-  }
502
-#endif
503
-
504
-  if (SWITicks) {
505
-    if (SWITicks < cpuLoopTicks)
506
-        cpuLoopTicks = SWITicks;
507
-  }
508
-
509
-  if (IRQTicks) {
510
-    if (IRQTicks < cpuLoopTicks)
511
-        cpuLoopTicks = IRQTicks;
512
-  }
513
-
514
-  return cpuLoopTicks;
515
-}
516
-
517
-/*void CPUUpdateWindow0()
518
-{
519
-  int x00 = WIN0H>>8;
520
-  int x01 = WIN0H & 255;
521
-
522
-  if(x00 <= x01) {
523
-    for(int i = 0; i < 240; i++) {
524
-      gfxInWin0[i] = (i >= x00 && i < x01);
525
-    }
526
-  } else {
527
-    for(int i = 0; i < 240; i++) {
528
-      gfxInWin0[i] = (i >= x00 || i < x01);
529
-    }
530
-  }
531
-}*/
532
-
533
-/*void CPUUpdateWindow1()
534
-{
535
-  int x00 = WIN1H>>8;
536
-  int x01 = WIN1H & 255;
537
-
538
-  if(x00 <= x01) {
539
-    for(int i = 0; i < 240; i++) {
540
-      gfxInWin1[i] = (i >= x00 && i < x01);
541
-    }
542
-  } else {
543
-    for(int i = 0; i < 240; i++) {
544
-      gfxInWin1[i] = (i >= x00 || i < x01);
545
-    }
546
-  }
547
-}*/
548
-
549
-/*extern uint32_t line0[240];
550
-extern uint32_t line1[240];
551
-extern uint32_t line2[240];
552
-extern uint32_t line3[240];
553
-
554
-#define CLEAR_ARRAY(a) \
555
-  {\
556
-    u32 *array = (a);\
557
-    for(int i = 0; i < 240; i++) {\
558
-      *array++ = 0x80000000;\
559
-    }\
560
-  }\*/
561
-
562
-/*void CPUUpdateRenderBuffers(bool force)
563
-{
564
-  if(!(layerEnable & 0x0100) || force) {
565
-    CLEAR_ARRAY(line0);
566
-  }
567
-  if(!(layerEnable & 0x0200) || force) {
568
-    CLEAR_ARRAY(line1);
569
-  }
570
-  if(!(layerEnable & 0x0400) || force) {
571
-    CLEAR_ARRAY(line2);
572
-  }
573
-  if(!(layerEnable & 0x0800) || force) {
574
-    CLEAR_ARRAY(line3);
575
-  }
576
-}*/
577
-
578
-/*static bool CPUWriteState(gzFile gzFile)
579
-{
580
-  utilWriteInt(gzFile, SAVE_GAME_VERSION);
581
-
582
-  utilGzWrite(gzFile, &rom[0xa0], 16);
583
-
584
-  utilWriteInt(gzFile, useBios);
585
-
586
-  utilGzWrite(gzFile, &reg[0], sizeof(reg));
587
-
588
-  utilWriteData(gzFile, saveGameStruct);
589
-
590
-  // new to version 0.7.1
591
-  utilWriteInt(gzFile, stopState);
592
-  // new to version 0.8
593
-  utilWriteInt(gzFile, IRQTicks);
594
-
595
-  utilGzWrite(gzFile, internalRAM, 0x8000);
596
-  utilGzWrite(gzFile, paletteRAM, 0x400);
597
-  utilGzWrite(gzFile, workRAM, 0x40000);
598
-  utilGzWrite(gzFile, vram, 0x20000);
599
-  utilGzWrite(gzFile, oam, 0x400);
600
-  utilGzWrite(gzFile, pix, 4*241*162);
601
-  utilGzWrite(gzFile, ioMem, 0x400);
602
-
603
-  eepromSaveGame(gzFile);
604
-  flashSaveGame(gzFile);
605
-  soundSaveGame(gzFile);
606
-
607
-  cheatsSaveGame(gzFile);
608
-
609
-  // version 1.5
610
-  rtcSaveGame(gzFile);
611
-
612
-  return true;
613
-}
614
-
615
-bool CPUWriteState(const char *file)
616
-{
617
-  gzFile gzFile = utilGzOpen(file, "wb");
618
-
619
-  if(gzFile == NULL) {
620
-    systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), file);
621
-    return false;
622
-  }
623
-
624
-  bool res = CPUWriteState(gzFile);
625
-
626
-  utilGzClose(gzFile);
627
-
628
-  return res;
629
-}
630
-
631
-bool CPUWriteMemState(char *memory, int available)
632
-{
633
-  gzFile gzFile = utilMemGzOpen(memory, available, "w");
634
-
635
-  if(gzFile == NULL) {
636
-    return false;
637
-  }
638
-
639
-  bool res = CPUWriteState(gzFile);
640
-
641
-  long pos = utilGzMemTell(gzFile)+8;
642
-
643
-  if(pos >= (available))
644
-    res = false;
645
-
646
-  utilGzClose(gzFile);
647
-
648
-  return res;
649
-}
650
-
651
-static bool CPUReadState(gzFile gzFile)
652
-{
653
-  int version = utilReadInt(gzFile);
654
-
655
-  if(version > SAVE_GAME_VERSION || version < SAVE_GAME_VERSION_1) {
656
-    systemMessage(MSG_UNSUPPORTED_VBA_SGM,
657
-                  N_("Unsupported VisualBoyAdvance save game version %d"),
658
-                  version);
659
-    return false;
660
-  }
661
-
662
-  u8 romname[17];
663
-
664
-  utilGzRead(gzFile, romname, 16);
665
-
666
-  if(memcmp(&rom[0xa0], romname, 16) != 0) {
667
-    romname[16]=0;
668
-    for(int i = 0; i < 16; i++)
669
-      if(romname[i] < 32)
670
-        romname[i] = 32;
671
-    systemMessage(MSG_CANNOT_LOAD_SGM, N_("Cannot load save game for %s"), romname);
672
-    return false;
673
-  }
674
-
675
-  bool ub = utilReadInt(gzFile) ? true : false;
676
-
677
-  if(ub != useBios) {
678
-    if(useBios)
679
-      systemMessage(MSG_SAVE_GAME_NOT_USING_BIOS,
680
-                    N_("Save game is not using the BIOS files"));
681
-    else
682
-      systemMessage(MSG_SAVE_GAME_USING_BIOS,
683
-                    N_("Save game is using the BIOS file"));
684
-    return false;
685
-  }
686
-
687
-  utilGzRead(gzFile, &reg[0], sizeof(reg));
688
-
689
-  utilReadData(gzFile, saveGameStruct);
690
-
691
-  if(version < SAVE_GAME_VERSION_3)
692
-    stopState = false;
693
-  else
694
-    stopState = utilReadInt(gzFile) ? true : false;
695
-
696
-  if(version < SAVE_GAME_VERSION_4)
697
-  {
698
-    IRQTicks = 0;
699
-    intState = false;
700
-  }
701
-  else
702
-  {
703
-    IRQTicks = utilReadInt(gzFile);
704
-    if (IRQTicks>0)
705
-      intState = true;
706
-    else
707
-    {
708
-      intState = false;
709
-      IRQTicks = 0;
710
-    }
711
-  }
712
-
713
-  utilGzRead(gzFile, internalRAM, 0x8000);
714
-  utilGzRead(gzFile, paletteRAM, 0x400);
715
-  utilGzRead(gzFile, workRAM, 0x40000);
716
-  utilGzRead(gzFile, vram, 0x20000);
717
-  utilGzRead(gzFile, oam, 0x400);
718
-  if(version < SAVE_GAME_VERSION_6)
719
-    utilGzRead(gzFile, pix, 4*240*160);
720
-  else
721
-    utilGzRead(gzFile, pix, 4*241*162);
722
-  utilGzRead(gzFile, ioMem, 0x400);
723
-
724
-  if(skipSaveGameBattery) {
725
-    // skip eeprom data
726
-    eepromReadGameSkip(gzFile, version);
727
-    // skip flash data
728
-    flashReadGameSkip(gzFile, version);
729
-  } else {
730
-    eepromReadGame(gzFile, version);
731
-    flashReadGame(gzFile, version);
732
-  }
733
-  soundReadGame(gzFile, version);
734
-
735
-  if(version > SAVE_GAME_VERSION_1) {
736
-    if(skipSaveGameCheats) {
737
-      // skip cheats list data
738
-      cheatsReadGameSkip(gzFile, version);
739
-    } else {
740
-      cheatsReadGame(gzFile, version);
741
-    }
742
-  }
743
-  if(version > SAVE_GAME_VERSION_6) {
744
-    rtcReadGame(gzFile);
745
-  }
746
-
747
-  if(version <= SAVE_GAME_VERSION_7) {
748
-    u32 temp;
749
-#define SWAP(a,b,c) \
750
-    temp = (a);\
751
-    (a) = (b)<<16|(c);\
752
-    (b) = (temp) >> 16;\
753
-    (c) = (temp) & 0xFFFF;
754
-
755
-    SWAP(dma0Source, DM0SAD_H, DM0SAD_L);
756
-    SWAP(dma0Dest,   DM0DAD_H, DM0DAD_L);
757
-    SWAP(dma1Source, DM1SAD_H, DM1SAD_L);
758
-    SWAP(dma1Dest,   DM1DAD_H, DM1DAD_L);
759
-    SWAP(dma2Source, DM2SAD_H, DM2SAD_L);
760
-    SWAP(dma2Dest,   DM2DAD_H, DM2DAD_L);
761
-    SWAP(dma3Source, DM3SAD_H, DM3SAD_L);
762
-    SWAP(dma3Dest,   DM3DAD_H, DM3DAD_L);
763
-  }
764
-
765
-  if(version <= SAVE_GAME_VERSION_8) {
766
-    timer0ClockReload = TIMER_TICKS[TM0CNT & 3];
767
-    timer1ClockReload = TIMER_TICKS[TM1CNT & 3];
768
-    timer2ClockReload = TIMER_TICKS[TM2CNT & 3];
769
-    timer3ClockReload = TIMER_TICKS[TM3CNT & 3];
770
-
771
-    timer0Ticks = ((0x10000 - TM0D) << timer0ClockReload) - timer0Ticks;
772
-    timer1Ticks = ((0x10000 - TM1D) << timer1ClockReload) - timer1Ticks;
773
-    timer2Ticks = ((0x10000 - TM2D) << timer2ClockReload) - timer2Ticks;
774
-    timer3Ticks = ((0x10000 - TM3D) << timer3ClockReload) - timer3Ticks;
775
-    interp_rate();
776
-  }
777
-
778
-  // set pointers!
779
-  layerEnable = layerSettings & DISPCNT;
780
-
781
-  CPUUpdateRender();
782
-  //CPUUpdateRenderBuffers(true);
783
-  //CPUUpdateWindow0();
784
-  //CPUUpdateWindow1();
785
-  gbaSaveType = 0;
786
-  switch(saveType) {
787
-  case 0:
788
-    cpuSaveGameFunc = flashSaveDecide;
789
-    break;
790
-  case 1:
791
-    cpuSaveGameFunc = sramWrite;
792
-    gbaSaveType = 1;
793
-    break;
794
-  case 2:
795
-    cpuSaveGameFunc = flashWrite;
796
-    gbaSaveType = 2;
797
-    break;
798
-  case 3:
799
-     break;
800
-  case 5:
801
-    gbaSaveType = 5;
802
-    break;
803
-  default:
804
-    systemMessage(MSG_UNSUPPORTED_SAVE_TYPE,
805
-                  N_("Unsupported save type %d"), saveType);
806
-    break;
807
-  }
808
-  if(eepromInUse)
809
-    gbaSaveType = 3;
810
-
811
-  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
812
-  if(armState) {
813
-    ARM_PREFETCH;
814
-  } else {
815
-    THUMB_PREFETCH;
816
-  }
817
-
818
-  CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204));
819
-
820
-  return true;
821
-}
822
-
823
-bool CPUReadMemState(char *memory, int available)
824
-{
825
-  gzFile gzFile = utilMemGzOpen(memory, available, "r");
826
-
827
-  bool res = CPUReadState(gzFile);
828
-
829
-  utilGzClose(gzFile);
830
-
831
-  return res;
832
-}
833
-
834
-bool CPUReadState(const char * file)
272
+static inline int CPUUpdateTicks()
835 273
 {
836
-  gzFile gzFile = utilGzOpen(file, "rb");
837
-
838
-  if(gzFile == NULL)
839
-    return false;
840
-
841
-  bool res = CPUReadState(gzFile);
842
-
843
-  utilGzClose(gzFile);
274
+	int cpuLoopTicks = lcdTicks;
844 275
 
845
-  return res;
846
-}
276
+	if (soundTicks < cpuLoopTicks)
277
+		cpuLoopTicks = soundTicks;
847 278
 
848
-bool CPUExportEepromFile(const char *fileName)
849
-{
850
-  if(eepromInUse) {
851
-    FILE *file = fopen(fileName, "wb");
852
-
853
-    if(!file) {
854
-      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
855
-                    fileName);
856
-      return false;
857
-    }
858
-
859
-    for(int i = 0; i < eepromSize;) {
860
-      for(int j = 0; j < 8; j++) {
861
-        if(fwrite(&eepromData[i+7-j], 1, 1, file) != 1) {
862
-          fclose(file);
863
-          return false;
864
-        }
865
-      }
866
-      i += 8;
867
-    }
868
-    fclose(file);
869
-  }
870
-  return true;
871
-}
279
+	if (timer0On && timer0Ticks < cpuLoopTicks)
280
+		cpuLoopTicks = timer0Ticks;
281
+	if (timer1On && !(TM1CNT & 4) && timer1Ticks < cpuLoopTicks)
282
+		cpuLoopTicks = timer1Ticks;
283
+	if (timer2On && !(TM2CNT & 4) && timer2Ticks < cpuLoopTicks)
284
+		cpuLoopTicks = timer2Ticks;
285
+	if (timer3On && !(TM3CNT & 4) && timer3Ticks < cpuLoopTicks)
286
+		cpuLoopTicks = timer3Ticks;
872 287
 
873
-bool CPUWriteBatteryFile(const char *fileName)
874
-{
875
-  if(gbaSaveType == 0) {
876
-    if(eepromInUse)
877
-      gbaSaveType = 3;
878
-    else switch(saveType) {
879
-    case 1:
880
-      gbaSaveType = 1;
881
-      break;
882
-    case 2:
883
-      gbaSaveType = 2;
884
-      break;
885
-    }
886
-  }
887
-
888
-  if((gbaSaveType) && (gbaSaveType!=5)) {
889
-    FILE *file = fopen(fileName, "wb");
890
-
891
-    if(!file) {
892
-      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
893
-                    fileName);
894
-      return false;
895
-    }
896
-
897
-    // only save if Flash/Sram in use or EEprom in use
898
-    if(gbaSaveType != 3) {
899
-      if(gbaSaveType == 2) {
900
-        if(fwrite(flashSaveMemory, 1, flashSize, file) != (size_t)flashSize) {
901
-          fclose(file);
902
-          return false;
903
-        }
904
-      } else {
905
-        if(fwrite(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
906
-          fclose(file);
907
-          return false;
908
-        }
909
-      }
910
-    } else {
911
-      if(fwrite(eepromData, 1, eepromSize, file) != (size_t)eepromSize) {
912
-        fclose(file);
913
-        return false;
914
-      }
915
-    }
916
-    fclose(file);
917
-  }
918
-  return true;
919
-}
288
+	if (SWITicks && SWITicks < cpuLoopTicks)
289
+		cpuLoopTicks = SWITicks;
920 290
 
921
-bool CPUReadGSASnapshot(const char *fileName)
922
-{
923
-  int i;
924
-  FILE *file = fopen(fileName, "rb");
925
-
926
-  if(!file) {
927
-    systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
928
-    return false;
929
-  }
930
-
931
-  // check file size to know what we should read
932
-  fseek(file, 0, SEEK_END);
933
-
934
-  // long size = ftell(file);
935
-  fseek(file, 0x0, SEEK_SET);
936
-  fread(&i, 1, 4, file);
937
-  fseek(file, i, SEEK_CUR); // Skip SharkPortSave
938
-//  fseek(file, 4, SEEK_CUR); // skip some sort of flag
939
-  fread(&i, 1, 4, file); // name length
940
-  fseek(file, i, SEEK_CUR); // skip name
941
-  fread(&i, 1, 4, file); // desc length
942
-  fseek(file, i, SEEK_CUR); // skip desc
943
-  fread(&i, 1, 4, file); // notes length
944
-  fseek(file, i, SEEK_CUR); // skip notes
945
-  int saveSize;
946
-  fread(&saveSize, 1, 4, file); // read length
947
-  saveSize -= 0x1c; // remove header size
948
-  char buffer[17];
949
-  char buffer2[17];
950
-  fread(buffer, 1, 16, file);
951
-  buffer[16] = 0;
952
-  for(i = 0; i < 16; i++)
953
-    if(buffer[i] < 32)
954
-      buffer[i] = 32;
955
-  memcpy(buffer2, &rom[0xa0], 16);
956
-  buffer2[16] = 0;
957
-  for(i = 0; i < 16; i++)
958
-    if(buffer2[i] < 32)
959
-      buffer2[i] = 32;
960
-  if(memcmp(buffer, buffer2, 16)) {
961
-    systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
962
-                  N_("Cannot import snapshot for %s. Current game is %s"),
963
-                  buffer,
964
-                  buffer2);
965
-    fclose(file);
966
-    return false;
967
-  }
968
-  fseek(file, 12, SEEK_CUR); // skip some flags
969
-  if(saveSize >= 65536) {
970
-    if(fread(flashSaveMemory, 1, saveSize, file) != (size_t)saveSize) {
971
-      fclose(file);
972
-      return false;
973
-    }
974
-  } else {
975
-    systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE,
976
-                  N_("Unsupported snapshot file %s"),
977
-                  fileName);
978
-    fclose(file);
979
-    return false;
980
-  }
981
-  fclose(file);
982
-  CPUReset();
983
-  return true;
984
-}
291
+	if (IRQTicks && IRQTicks < cpuLoopTicks)
292
+		cpuLoopTicks = IRQTicks;
985 293
 
986
-bool CPUReadGSASPSnapshot(const char *fileName)
987
-{
988
-  const char gsvfooter[] = "xV4\x12";
989
-  const size_t namepos=0x0c, namesz=12;
990
-  const size_t footerpos=0x42c, footersz=4;
991
-
992
-  char footer[footersz+1], romname[namesz+1], savename[namesz+1];;
993
-  FILE *file = fopen(fileName, "rb");
994
-
995
-  if(!file) {
996
-    systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
997
-    return false;
998
-  }
999
-
1000
-  // read save name
1001
-  fseek(file, namepos, SEEK_SET);
1002
-  fread(savename, 1, namesz, file);
1003
-  savename[namesz] = 0;
1004
-
1005
-  memcpy(romname, &rom[0xa0], namesz);
1006
-  romname[namesz] = 0;
1007
-
1008
-  if(memcmp(romname, savename, namesz)) {
1009
-    systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
1010
-                  N_("Cannot import snapshot for %s. Current game is %s"),
1011
-                  savename,
1012
-                  romname);
1013
-    fclose(file);
1014
-    return false;
1015
-  }
1016
-
1017
-  // read footer tag
1018
-  fseek(file, footerpos, SEEK_SET);
1019
-  fread(footer, 1, footersz, file);
1020
-  footer[footersz] = 0;
1021
-
1022
-  if(memcmp(footer, gsvfooter, footersz)) {
1023
-    systemMessage(0,
1024
-                  N_("Unsupported snapshot file %s. Footer '%s' at %u should be '%s'"),
1025
-                  fileName,
1026
-				  footer,
1027
-                  footerpos,
1028
-				  gsvfooter);
1029
-    fclose(file);
1030
-    return false;
1031
-  }
1032
-
1033
-  // Read up to 128k save
1034
-  fread(flashSaveMemory, 1, FLASH_128K_SZ, file);
1035
-
1036
-  fclose(file);
1037
-  CPUReset();
1038
-  return true;
294
+	return cpuLoopTicks;
1039 295
 }
1040 296
 
1041
-
1042
-bool CPUWriteGSASnapshot(const char *fileName,
1043
-                         const char *title,
1044
-                         const char *desc,
1045
-                         const char *notes)
297
+int CPULoadRom()
1046 298
 {
1047
-  FILE *file = fopen(fileName, "wb");
1048
-
1049
-  if(!file) {
1050
-    systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
1051
-    return false;
1052
-  }
1053
-
1054
-  u8 buffer[17];
1055
-
1056
-  utilPutDword(buffer, 0x0d); // SharkPortSave length
1057
-  fwrite(buffer, 1, 4, file);
1058
-  fwrite("SharkPortSave", 1, 0x0d, file);
1059
-  utilPutDword(buffer, 0x000f0000);
1060
-  fwrite(buffer, 1, 4, file); // save type 0x000f0000 = GBA save
1061
-  utilPutDword(buffer, (u32)strlen(title));
1062
-  fwrite(buffer, 1, 4, file); // title length
1063
-  fwrite(title, 1, strlen(title), file);
1064
-  utilPutDword(buffer, (u32)strlen(desc));
1065
-  fwrite(buffer, 1, 4, file); // desc length
1066
-  fwrite(desc, 1, strlen(desc), file);
1067
-  utilPutDword(buffer, (u32)strlen(notes));
1068
-  fwrite(buffer, 1, 4, file); // notes length
1069
-  fwrite(notes, 1, strlen(notes), file);
1070
-  int saveSize = 0x10000;
1071
-  if(gbaSaveType == 2)
1072
-    saveSize = flashSize;
1073
-  int totalSize = saveSize + 0x1c;
1074
-
1075
-  utilPutDword(buffer, totalSize); // length of remainder of save - CRC
1076
-  fwrite(buffer, 1, 4, file);
1077
-
1078
-  char *temp = new char[0x2001c];
1079
-  memset(temp, 0, 28);
1080
-  memcpy(temp, &rom[0xa0], 16); // copy internal name
1081
-  temp[0x10] = rom[0xbe]; // reserved area (old checksum)
1082
-  temp[0x11] = rom[0xbf]; // reserved area (old checksum)
1083
-  temp[0x12] = rom[0xbd]; // complement check
1084
-  temp[0x13] = rom[0xb0]; // maker
1085
-  temp[0x14] = 1; // 1 save ?
1086
-  memcpy(&temp[0x1c], flashSaveMemory, saveSize); // copy save
1087
-  fwrite(temp, 1, totalSize, file); // write save + header
1088
-  u32 crc = 0;
1089
-
1090
-  for(int i = 0; i < totalSize; i++) {
1091
-    crc += ((u32)temp[i] << (crc % 0x18));
1092
-  }
1093
-
1094
-  utilPutDword(buffer, crc);
1095
-  fwrite(buffer, 1, 4, file); // CRC?
1096
-
1097
-  fclose(file);
1098
-  delete [] temp;
1099
-  return true;
1100
-}
299
+	romSize = 0x2000000;
1101 300
 
1102
-bool CPUImportEepromFile(const char *fileName)
1103
-{
1104
-  FILE *file = fopen(fileName, "rb");
1105
-
1106
-  if(!file)
1107
-    return false;
1108
-
1109
-  // check file size to know what we should read
1110
-  fseek(file, 0, SEEK_END);
1111
-
1112
-  long size = ftell(file);
1113
-  fseek(file, 0, SEEK_SET);
1114
-  if(size == 512 || size == 0x2000) {
1115
-    if(fread(eepromData, 1, size, file) != (size_t)size) {
1116
-      fclose(file);
1117
-      return false;
1118
-    }
1119
-    for(int i = 0; i < size;) {
1120
-      u8 tmp = eepromData[i];
1121
-      eepromData[i] = eepromData[7-i];
1122
-      eepromData[7-i] = tmp;
1123
-      i++;
1124
-      tmp = eepromData[i];
1125
-      eepromData[i] = eepromData[7-i];
1126
-      eepromData[7-i] = tmp;
1127
-      i++;
1128
-      tmp = eepromData[i];
1129
-      eepromData[i] = eepromData[7-i];
1130
-      eepromData[7-i] = tmp;
1131
-      i++;
1132
-      tmp = eepromData[i];
1133
-      eepromData[i] = eepromData[7-i];
1134
-      eepromData[7-i] = tmp;
1135
-      i++;
1136
-      i += 4;
1137
-    }
1138
-  } else {
1139
-    fclose(file);
1140
-    return false;
1141
-  }
1142
-  fclose(file);
1143
-  return true;
1144
-}
301
+	memset(&workRAM[0], 0, 0x40000);
1145 302
 
1146
-bool CPUReadBatteryFile(const char *fileName)
1147
-{
1148
-  FILE *file = fopen(fileName, "rb");
1149
-
1150
-  if(!file)
1151
-    return false;
1152
-
1153
-  // check file size to know what we should read
1154
-  fseek(file, 0, SEEK_END);
1155
-
1156
-  long size = ftell(file);
1157
-  fseek(file, 0, SEEK_SET);
1158
-  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
1159
-
1160
-  if(size == 512 || size == 0x2000) {
1161
-    if(fread(eepromData, 1, size, file) != (size_t)size) {
1162
-      fclose(file);
1163
-      return false;
1164
-    }
1165
-  } else {
1166
-    if(size == 0x20000) {
1167
-      if(fread(flashSaveMemory, 1, 0x20000, file) != 0x20000) {
1168
-        fclose(file);
1169
-        return false;
1170
-      }
1171
-      flashSetSize(0x20000);
1172
-    } else {
1173
-      if(fread(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
1174
-        fclose(file);
1175
-        return false;
1176
-      }
1177
-      flashSetSize(0x10000);
1178
-    }
1179
-  }
1180
-  fclose(file);
1181
-  return true;
1182
-}
1183
-
1184
-bool CPUWritePNGFile(const char *fileName)
1185
-{
1186
-  return utilWritePNGFile(fileName, 240, 160, pix);
1187
-}
1188
-
1189
-bool CPUWriteBMPFile(const char *fileName)
1190
-{
1191
-  return utilWriteBMPFile(fileName, 240, 160, pix);
1192
-}*/
1193
-
1194
-bool CPUIsZipFile(const char * file)
1195
-{
1196
-  if(strlen(file) > 4) {
1197
-    const char * p = strrchr(file,'.');
1198
-
1199
-    if(p != NULL) {
1200
-      if(_stricmp(p, ".zip") == 0)
1201
-        return true;
1202
-    }
1203
-  }
1204
-
1205
-  return false;
1206
-}
1207
-
1208
-bool CPUIsGBAImage(const char * file)
1209
-{
1210
-  cpuIsMultiBoot = false;
1211
-  if(strlen(file) > 4) {
1212
-    const char * p = strrchr(file,'.');
1213
-
1214
-    if(p != NULL) {
1215
-      if(_stricmp(p, ".gba") == 0)
1216
-        return true;
1217
-      if(_stricmp(p, ".agb") == 0)
1218
-        return true;
1219
-      if(_stricmp(p, ".bin") == 0)
1220
-        return true;
1221
-      if(_stricmp(p, ".elf") == 0)
1222
-        return true;
1223
-      if(_stricmp(p, ".mb") == 0) {
1224
-        cpuIsMultiBoot = true;
1225
-        return true;
1226
-      }
1227
-    }
1228
-  }
1229
-
1230
-  return false;
1231
-}
1232
-
1233
-bool CPUIsGBABios(const char * file)
1234
-{
1235
-  if(strlen(file) > 4) {
1236
-    const char * p = strrchr(file,'.');
1237
-
1238
-    if(p != NULL) {
1239
-      if(_stricmp(p, ".gba") == 0)
1240
-        return true;
1241
-      if(_stricmp(p, ".agb") == 0)
1242
-        return true;
1243
-      if(_stricmp(p, ".bin") == 0)
1244
-        return true;
1245
-      if(_stricmp(p, ".bios") == 0)
1246
-        return true;
1247
-      if(_stricmp(p, ".rom") == 0)
1248
-        return true;
1249
-    }
1250
-  }
1251
-
1252
-  return false;
1253
-}
1254
-
1255
-bool CPUIsELF(const char *file)
1256
-{
1257
-  if(file == NULL)
1258
-	  return false;
1259
-
1260
-  if(strlen(file) > 4) {
1261
-    const char * p = strrchr(file,'.');
1262
-
1263
-    if(p != NULL) {
1264
-      if(_stricmp(p, ".elf") == 0)
1265
-        return true;
1266
-    }
1267
-  }
1268
-  return false;
1269
-}
1270
-
1271
-void CPUCleanUp()
1272
-{
1273
-#ifdef PROFILING
1274
-  if(profilingTicksReload) {
1275
-    profCleanup();
1276
-  }
1277
-#endif
1278
-
1279
-  if(rom != NULL) {
1280
-    free(rom);
1281
-    rom = NULL;
1282
-  }
1283
-
1284
-  if(vram != NULL) {
1285
-    free(vram);
1286
-    vram = NULL;
1287
-  }
1288
-
1289
-  if(paletteRAM != NULL) {
1290
-    free(paletteRAM);
1291
-    paletteRAM = NULL;
1292
-  }
1293
-
1294
-  if(internalRAM != NULL) {
1295
-    free(internalRAM);
1296
-    internalRAM = NULL;
1297
-  }
1298
-
1299
-  if(workRAM != NULL) {
1300
-    free(workRAM);
1301
-    workRAM = NULL;
1302
-  }
1303
-
1304
-  if(bios != NULL) {
1305
-    free(bios);
1306
-    bios = NULL;
1307
-  }
1308
-
1309
-  if(pix != NULL) {
1310
-    free(pix);
1311
-    pix = NULL;
1312
-  }
1313
-
1314
-  if(oam != NULL) {
1315
-    free(oam);
1316
-    oam = NULL;
1317
-  }
1318
-
1319
-  if(ioMem != NULL) {
1320
-    free(ioMem);
1321
-    ioMem = NULL;
1322
-  }
1323
-
1324
-#ifndef NO_DEBUGGER
1325
-  elfCleanUp();
1326
-#endif //NO_DEBUGGER
1327
-
1328
-  //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
1329
-
1330
-  //emulating = 0;
1331
-}
1332
-
1333
-int CPULoadRom(const char *szFile)
1334
-{
1335
-  romSize = 0x2000000;
1336
-  if(rom != NULL) {
1337
-    CPUCleanUp();
1338
-  }
1339
-
1340
-  //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
1341
-
1342
-  rom = (uint8_t *)malloc(0x2000000);
1343
-  if(rom == NULL) {
1344
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1345
-                  "ROM");*/
1346
-    return 0;
1347
-  }
1348
-  workRAM = (uint8_t *)calloc(1, 0x40000);
1349
-  if(workRAM == NULL) {
1350
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1351
-                  "WRAM");*/
1352
-    return 0;
1353
-  }
1354
-
1355
-  //u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom;
1356
-
1357
-#ifndef NO_DEBUGGER
1358
-  if(CPUIsELF(szFile)) {
1359
-    FILE *f = fopen(szFile, "rb");
1360
-    if(!f) {
1361
-      systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"),
1362
-                    szFile);
1363
-      free(rom);
1364
-      rom = NULL;
1365
-      free(workRAM);
1366
-      workRAM = NULL;
1367
-      return 0;
1368
-    }
1369
-    bool res = elfRead(szFile, romSize, f);
1370
-    if(!res || romSize == 0) {
1371
-      free(rom);
1372
-      rom = NULL;
1373
-      free(workRAM);
1374
-      workRAM = NULL;
1375
-      elfCleanUp();
1376
-      return 0;
1377
-    }
1378
-  } else
1379
-#endif //NO_DEBUGGER
1380
-  /*if(szFile!=NULL)
1381
-  {
1382
-	  if(!utilLoad(szFile,
1383
-						  utilIsGBAImage,
1384
-						  whereToLoad,
1385
-						  romSize)) {
1386
-		free(rom);
1387
-		rom = NULL;
1388
-		free(workRAM);
1389
-		workRAM = NULL;
1390
-		return 0;
1391
-	  }
1392
-  }*/
1393 303
 	if (cpuIsMultiBoot)
1394
-		mapgsf(workRAM,0x40000,romSize);
304
+		mapgsf(workRAM, 0x40000, romSize);
1395 305
 	else
1396
-		mapgsf(rom, 0x2000000,romSize);
1397
-
1398
-  uint16_t *temp = (uint16_t *)(rom+((romSize+1)&~1));
1399
-  int i;
1400
-  for(i = (romSize+1)&~1; i < 0x2000000; i+=2) {
1401
-    WRITE16LE(temp, (i >> 1) & 0xFFFF);
1402
-    temp++;
1403
-  }
1404
-
1405
-  bios = (uint8_t *)calloc(1,0x4000);
1406
-  if(bios == NULL) {
1407
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1408
-                  "BIOS");*/
1409
-    CPUCleanUp();
1410
-    return 0;
1411
-  }
1412
-  internalRAM = (uint8_t *)calloc(1,0x8000);
1413
-  if(internalRAM == NULL) {
1414
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1415
-                  "IRAM");*/
1416
-    CPUCleanUp();
1417
-    return 0;
1418
-  }
1419
-  paletteRAM = (uint8_t *)calloc(1,0x400);
1420
-  if(paletteRAM == NULL) {
1421
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1422
-                  "PRAM");*/
1423
-    CPUCleanUp();
1424
-    return 0;
1425
-  }
1426
-  vram = (uint8_t *)calloc(1, 0x20000);
1427
-  if(vram == NULL) {
1428
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1429
-                  "VRAM");*/
1430
-    CPUCleanUp();
1431
-    return 0;
1432
-  }
1433
-  oam = (uint8_t *)calloc(1, 0x400);
1434
-  if(oam == NULL) {
1435
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1436
-                  "OAM");*/
1437
-    CPUCleanUp();
1438
-    return 0;
1439
-  }
1440
-  pix = (uint8_t *)calloc(1, 4 * 241 * 162);
1441
-  if(pix == NULL) {
1442
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1443
-                  "PIX");*/
1444
-    CPUCleanUp();
1445
-    return 0;
1446
-  }
1447
-  ioMem = (uint8_t *)calloc(1, 0x400);
1448
-  if(ioMem == NULL) {
1449
-    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1450
-                  "IO");*/
1451
-    CPUCleanUp();
1452
-    return 0;
1453
-  }
1454
-
1455
-  //flashInit();
1456
-  //eepromInit();
1457
-
1458
-  //CPUUpdateRenderBuffers(true);
1459
-
1460
-  return romSize;
306
+		mapgsf(rom, 0x2000000, romSize);
307
+
308
+	uint16_t *temp = reinterpret_cast<uint16_t *>(rom + ((romSize + 1) & ~1));
309
+	int i;
310
+	for (i = (romSize + 1) & ~1; i < 0x2000000; i += 2)
311
+	{
312
+		WRITE16LE(temp, (i >> 1) & 0xFFFF);
313
+		++temp;
314
+	}
315
+
316
+	memset(&bios[0], 0, 0x4000);
317
+	memset(&internalRAM[0], 0, 0x8000);
318
+	memset(&paletteRAM[0], 0, 0x400);
319
+	memset(&vram[0], 0, 0x20000);
320
+	memset(&oam[0], 0, 0x400);
321
+	memset(&ioMem[0], 0, 0x400);
322
+
323
+	return romSize;
1461 324
 }
1462 325
 
1463
-void doMirroring (bool b)
1464
-{
1465
-  uint32_t mirroredRomSize = (((romSize)>>20) & 0x3F)<<20;
1466
-  uint32_t mirroredRomAddress = romSize;
1467
-  if ((mirroredRomSize <=0x800000) && (b))
1468
-  {
1469
-    mirroredRomAddress = mirroredRomSize;
1470
-    if (mirroredRomSize==0)
1471
-        mirroredRomSize=0x100000;
1472
-    while (mirroredRomAddress<0x01000000)
1473
-    {
1474
-      memcpy ((uint16_t *)(rom+mirroredRomAddress), (uint16_t *)(rom), mirroredRomSize);
1475
-      mirroredRomAddress+=mirroredRomSize;
1476
-    }
1477
-  }
1478
-}
1479
-
1480
-/*void CPUUpdateRender()
1481
-{
1482
-  switch(DISPCNT & 7) {
1483
-  case 0:
1484
-    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1485
-       cpuDisableSfx)
1486
-      renderLine = mode0RenderLine;
1487
-    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1488
-      renderLine = mode0RenderLineNoWindow;
1489
-    else
1490
-      renderLine = mode0RenderLineAll;
1491
-    break;
1492
-  case 1:
1493
-    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1494
-       cpuDisableSfx)
1495
-      renderLine = mode1RenderLine;
1496
-    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1497
-      renderLine = mode1RenderLineNoWindow;
1498
-    else
1499
-      renderLine = mode1RenderLineAll;
1500
-    break;
1501
-  case 2:
1502
-    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1503
-       cpuDisableSfx)
1504
-      renderLine = mode2RenderLine;
1505
-    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1506
-      renderLine = mode2RenderLineNoWindow;
1507
-    else
1508
-      renderLine = mode2RenderLineAll;
1509
-    break;
1510
-  case 3:
1511
-    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1512
-       cpuDisableSfx)
1513
-      renderLine = mode3RenderLine;
1514
-    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1515
-      renderLine = mode3RenderLineNoWindow;
1516
-    else
1517
-      renderLine = mode3RenderLineAll;
1518
-    break;
1519
-  case 4:
1520
-    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1521
-       cpuDisableSfx)
1522
-      renderLine = mode4RenderLine;
1523
-    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1524
-      renderLine = mode4RenderLineNoWindow;
1525
-    else
1526
-      renderLine = mode4RenderLineAll;
1527
-    break;
1528
-  case 5:
1529
-    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1530
-       cpuDisableSfx)
1531
-      renderLine = mode5RenderLine;
1532
-    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1533
-      renderLine = mode5RenderLineNoWindow;
1534
-    else
1535
-      renderLine = mode5RenderLineAll;
1536
-  default:
1537
-    break;
1538
-  }
1539
-}*/
1540
-
1541 326
 void CPUUpdateCPSR()
1542 327
 {
1543
-  uint32_t CPSR = reg[16].I & 0x40;
1544
-  if(N_FLAG)
1545
-    CPSR |= 0x80000000;
1546
-  if(Z_FLAG)
1547
-    CPSR |= 0x40000000;
1548
-  if(C_FLAG)
1549
-    CPSR |= 0x20000000;
1550
-  if(V_FLAG)
1551
-    CPSR |= 0x10000000;
1552
-  if(!armState)
1553
-    CPSR |= 0x00000020;
1554
-  if(!armIrqEnable)
1555
-    CPSR |= 0x80;
1556
-  CPSR |= (armMode & 0x1F);
1557
-  reg[16].I = CPSR;
328
+	uint32_t CPSR = reg[16].I & 0x40;
329
+	if (N_FLAG)
330
+		CPSR |= 0x80000000;
331
+	if (Z_FLAG)
332
+		CPSR |= 0x40000000;
333
+	if (C_FLAG)
334
+		CPSR |= 0x20000000;
335
+	if (V_FLAG)
336
+		CPSR |= 0x10000000;
337
+	if (!armState)
338
+		CPSR |= 0x00000020;
339
+	if (!armIrqEnable)
340
+		CPSR |= 0x80;
341
+	CPSR |= armMode & 0x1F;
342
+	reg[16].I = CPSR;
1558 343
 }
1559 344
 
1560 345
 void CPUUpdateFlags(bool breakLoop)
1561 346
 {
1562
-  uint32_t CPSR = reg[16].I;
1563
-
1564
-  N_FLAG = (CPSR & 0x80000000) ? true: false;
1565
-  Z_FLAG = (CPSR & 0x40000000) ? true: false;
1566
-  C_FLAG = (CPSR & 0x20000000) ? true: false;
1567
-  V_FLAG = (CPSR & 0x10000000) ? true: false;
1568
-  armState = (CPSR & 0x20) ? false : true;
1569
-  armIrqEnable = (CPSR & 0x80) ? false : true;
1570
-  if(breakLoop) {
1571
-      if (armIrqEnable && (IF & IE) && (IME & 1))
1572
-        cpuNextEvent = cpuTotalTicks;
1573
-  }
1574
-}
1575
-
1576
-void CPUUpdateFlags()
1577
-{
1578
-  CPUUpdateFlags(true);
347
+	uint32_t CPSR = reg[16].I;
348
+
349
+	N_FLAG = !!(CPSR & 0x80000000);
350
+	Z_FLAG = !!(CPSR & 0x40000000);
351
+	C_FLAG = !!(CPSR & 0x20000000);
352
+	V_FLAG = !!(CPSR & 0x10000000);
353
+	armState = !(CPSR & 0x20);
354
+	armIrqEnable = !(CPSR & 0x80);
355
+	if (breakLoop && armIrqEnable && (IF & IE) && (IME & 1))
356
+		cpuNextEvent = cpuTotalTicks;
1579 357
 }
1580 358
 
1581
-#ifdef WORDS_BIGENDIAN
1582
-static void CPUSwap(volatile uint32_t *a, volatile uint32_t *b)
1583
-{
1584
-  volatile uint32_t c = *b;
1585
-  *b = *a;
1586
-  *a = c;
1587
-}
1588
-#else
1589
-static void CPUSwap(uint32_t *a, uint32_t *b)
1590
-{
1591
-  uint32_t c = *b;
1592
-  *b = *a;
1593
-  *a = c;
1594
-}
1595
-#endif
1596
-
1597 359
 void CPUSwitchMode(int mode, bool saveState, bool breakLoop)
1598 360
 {
1599
-  //  if(armMode == mode)
1600
-  //    return;
1601
-
1602
-  CPUUpdateCPSR();
1603
-
1604
-  switch(armMode) {
1605
-  case 0x10:
1606
-  case 0x1F:
1607
-    reg[R13_USR].I = reg[13].I;
1608
-    reg[R14_USR].I = reg[14].I;
1609
-    reg[17].I = reg[16].I;
1610
-    break;
1611
-  case 0x11:
1612
-    CPUSwap(&reg[R8_FIQ].I, &reg[8].I);
1613
-    CPUSwap(&reg[R9_FIQ].I, &reg[9].I);
1614
-    CPUSwap(&reg[R10_FIQ].I, &reg[10].I);
1615
-    CPUSwap(&reg[R11_FIQ].I, &reg[11].I);
1616
-    CPUSwap(&reg[R12_FIQ].I, &reg[12].I);
1617
-    reg[R13_FIQ].I = reg[13].I;
1618
-    reg[R14_FIQ].I = reg[14].I;
1619
-    reg[SPSR_FIQ].I = reg[17].I;
1620
-    break;
1621
-  case 0x12:
1622
-    reg[R13_IRQ].I  = reg[13].I;
1623
-    reg[R14_IRQ].I  = reg[14].I;
1624
-    reg[SPSR_IRQ].I =  reg[17].I;
1625
-    break;
1626
-  case 0x13:
1627
-    reg[R13_SVC].I  = reg[13].I;
1628
-    reg[R14_SVC].I  = reg[14].I;
1629
-    reg[SPSR_SVC].I =  reg[17].I;
1630
-    break;
1631
-  case 0x17:
1632
-    reg[R13_ABT].I  = reg[13].I;
1633
-    reg[R14_ABT].I  = reg[14].I;
1634
-    reg[SPSR_ABT].I =  reg[17].I;
1635
-    break;
1636
-  case 0x1b:
1637
-    reg[R13_UND].I  = reg[13].I;
1638
-    reg[R14_UND].I  = reg[14].I;
1639
-    reg[SPSR_UND].I =  reg[17].I;
1640
-    break;
1641
-  }
1642
-
1643
-  uint32_t CPSR = reg[16].I;
1644
-  uint32_t SPSR = reg[17].I;
1645
-
1646
-  switch(mode) {
1647
-  case 0x10:
1648
-  case 0x1F:
1649
-    reg[13].I = reg[R13_USR].I;
1650
-    reg[14].I = reg[R14_USR].I;
1651
-    reg[16].I = SPSR;
1652
-    break;
1653
-  case 0x11:
1654
-    CPUSwap(&reg[8].I, &reg[R8_FIQ].I);
1655
-    CPUSwap(&reg[9].I, &reg[R9_FIQ].I);
1656
-    CPUSwap(&reg[10].I, &reg[R10_FIQ].I);
1657
-    CPUSwap(&reg[11].I, &reg[R11_FIQ].I);
1658
-    CPUSwap(&reg[12].I, &reg[R12_FIQ].I);
1659
-    reg[13].I = reg[R13_FIQ].I;
1660
-    reg[14].I = reg[R14_FIQ].I;
1661
-    if(saveState)
1662
-      reg[17].I = CPSR;
1663
-    else
1664
-      reg[17].I = reg[SPSR_FIQ].I;
1665
-    break;
1666
-  case 0x12:
1667
-    reg[13].I = reg[R13_IRQ].I;
1668
-    reg[14].I = reg[R14_IRQ].I;
1669
-    reg[16].I = SPSR;
1670
-    if(saveState)
1671
-      reg[17].I = CPSR;
1672
-    else
1673
-      reg[17].I = reg[SPSR_IRQ].I;
1674
-    break;
1675
-  case 0x13:
1676
-    reg[13].I = reg[R13_SVC].I;
1677
-    reg[14].I = reg[R14_SVC].I;
1678
-    reg[16].I = SPSR;
1679
-    if(saveState)
1680
-      reg[17].I = CPSR;
1681
-    else
1682
-      reg[17].I = reg[SPSR_SVC].I;
1683
-    break;
1684
-  case 0x17:
1685
-    reg[13].I = reg[R13_ABT].I;
1686
-    reg[14].I = reg[R14_ABT].I;
1687
-    reg[16].I = SPSR;
1688
-    if(saveState)
1689
-      reg[17].I = CPSR;
1690
-    else
1691
-      reg[17].I = reg[SPSR_ABT].I;
1692
-    break;
1693
-  case 0x1b:
1694
-    reg[13].I = reg[R13_UND].I;
1695
-    reg[14].I = reg[R14_UND].I;
1696
-    reg[16].I = SPSR;
1697
-    if(saveState)
1698
-      reg[17].I = CPSR;
1699
-    else
1700
-      reg[17].I = reg[SPSR_UND].I;
1701
-    break;
1702
-  default:
1703
-    //systemMessage(MSG_UNSUPPORTED_ARM_MODE, N_("Unsupported ARM mode %02x"), mode);
1704
-    break;
1705
-  }
1706
-  armMode = mode;
1707
-  CPUUpdateFlags(breakLoop);
1708
-  CPUUpdateCPSR();
1709
-}
1710
-
1711
-void CPUSwitchMode(int mode, bool saveState)
1712
-{
1713
-  CPUSwitchMode(mode, saveState, true);
361
+	CPUUpdateCPSR();
362
+
363
+	switch (armMode)
364
+	{
365
+		case 0x10:
366
+		case 0x1F:
367
+			reg[R13_USR].I = reg[13].I;
368
+			reg[R14_USR].I = reg[14].I;
369
+			reg[17].I = reg[16].I;
370
+			break;
371
+		case 0x11:
372
+			std::swap(reg[R8_FIQ].I, reg[8].I);
373
+			std::swap(reg[R9_FIQ].I, reg[9].I);
374
+			std::swap(reg[R10_FIQ].I, reg[10].I);
375
+			std::swap(reg[R11_FIQ].I, reg[11].I);
376
+			std::swap(reg[R12_FIQ].I, reg[12].I);
377
+			reg[R13_FIQ].I = reg[13].I;
378
+			reg[R14_FIQ].I = reg[14].I;
379
+			reg[SPSR_FIQ].I = reg[17].I;
380
+			break;
381
+		case 0x12:
382
+			reg[R13_IRQ].I = reg[13].I;
383
+			reg[R14_IRQ].I = reg[14].I;
384
+			reg[SPSR_IRQ].I = reg[17].I;
385
+			break;
386
+		case 0x13:
387
+			reg[R13_SVC].I = reg[13].I;
388
+			reg[R14_SVC].I = reg[14].I;
389
+			reg[SPSR_SVC].I = reg[17].I;
390
+			break;
391
+		case 0x17:
392
+			reg[R13_ABT].I = reg[13].I;
393
+			reg[R14_ABT].I = reg[14].I;
394
+			reg[SPSR_ABT].I = reg[17].I;
395
+			break;
396
+		case 0x1b:
397
+			reg[R13_UND].I = reg[13].I;
398
+			reg[R14_UND].I = reg[14].I;
399
+			reg[SPSR_UND].I = reg[17].I;
400
+	}
401
+
402
+	uint32_t CPSR = reg[16].I;
403
+	uint32_t SPSR = reg[17].I;
404
+
405
+	switch (mode)
406
+	{
407
+		case 0x10:
408
+		case 0x1F:
409
+			reg[13].I = reg[R13_USR].I;
410
+			reg[14].I = reg[R14_USR].I;
411
+			reg[16].I = SPSR;
412
+			break;
413
+		case 0x11:
414
+			std::swap(reg[8].I, reg[R8_FIQ].I);
415
+			std::swap(reg[9].I, reg[R9_FIQ].I);
416
+			std::swap(reg[10].I, reg[R10_FIQ].I);
417
+			std::swap(reg[11].I, reg[R11_FIQ].I);
418
+			std::swap(reg[12].I, reg[R12_FIQ].I);
419
+			reg[13].I = reg[R13_FIQ].I;
420
+			reg[14].I = reg[R14_FIQ].I;
421
+			if (saveState)
422
+				reg[17].I = CPSR;
423
+			else
424
+				reg[17].I = reg[SPSR_FIQ].I;
425
+			break;
426
+		case 0x12:
427
+			reg[13].I = reg[R13_IRQ].I;
428
+			reg[14].I = reg[R14_IRQ].I;
429
+			reg[16].I = SPSR;
430
+			if (saveState)
431
+				reg[17].I = CPSR;
432
+			else
433
+				reg[17].I = reg[SPSR_IRQ].I;
434
+			break;
435
+		case 0x13:
436
+			reg[13].I = reg[R13_SVC].I;
437
+			reg[14].I = reg[R14_SVC].I;
438
+			reg[16].I = SPSR;
439
+			if (saveState)
440
+				reg[17].I = CPSR;
441
+			else
442
+				reg[17].I = reg[SPSR_SVC].I;
443
+			break;
444
+		case 0x17:
445
+			reg[13].I = reg[R13_ABT].I;
446
+			reg[14].I = reg[R14_ABT].I;
447
+			reg[16].I = SPSR;
448
+			if (saveState)
449
+				reg[17].I = CPSR;
450
+			else
451
+				reg[17].I = reg[SPSR_ABT].I;
452
+			break;
453
+		case 0x1b:
454
+			reg[13].I = reg[R13_UND].I;
455
+			reg[14].I = reg[R14_UND].I;
456
+			reg[16].I = SPSR;
457
+			if (saveState)
458
+				reg[17].I = CPSR;
459
+			else
460
+				reg[17].I = reg[SPSR_UND].I;
461
+	}
462
+	armMode = mode;
463
+	CPUUpdateFlags(breakLoop);
464
+	CPUUpdateCPSR();
1714 465
 }
1715 466
 
1716 467
 void CPUUndefinedException()
1717 468
 {
1718
-  uint32_t PC = reg[15].I;
1719
-  bool savedArmState = armState;
1720
-  CPUSwitchMode(0x1b, true, false);
1721
-  reg[14].I = PC - (savedArmState ? 4 : 2);
1722
-  reg[15].I = 0x04;
1723
-  armState = true;
1724
-  armIrqEnable = false;
1725
-  armNextPC = 0x04;
1726
-  ARM_PREFETCH;
1727
-  reg[15].I += 4;
469
+	uint32_t PC = reg[15].I;
470
+	bool savedArmState = armState;
471
+	CPUSwitchMode(0x1b, true, false);
472
+	reg[14].I = PC - (savedArmState ? 4 : 2);
473
+	reg[15].I = 0x04;
474
+	armState = true;
475
+	armIrqEnable = false;
476
+	armNextPC = 0x04;
477
+	ARM_PREFETCH();
478
+	reg[15].I += 4;
1728 479
 }
1729 480
 
1730 481
 void CPUSoftwareInterrupt()
1731 482
 {
1732
-  uint32_t PC = reg[15].I;
1733
-  bool savedArmState = armState;
1734
-  CPUSwitchMode(0x13, true, false);
1735
-  reg[14].I = PC - (savedArmState ? 4 : 2);
1736
-  reg[15].I = 0x08;
1737
-  armState = true;
1738
-  armIrqEnable = false;
1739
-  armNextPC = 0x08;
1740
-  ARM_PREFETCH;
1741
-  reg[15].I += 4;
483
+	uint32_t PC = reg[15].I;
484
+	bool savedArmState = armState;
485
+	CPUSwitchMode(0x13, true, false);
486
+	reg[14].I = PC - (savedArmState ? 4 : 2);
487
+	reg[15].I = 0x08;
488
+	armState = true;
489
+	armIrqEnable = false;
490
+	armNextPC = 0x08;
491
+	ARM_PREFETCH();
492
+	reg[15].I += 4;
1742 493
 }
1743 494
 
1744 495
 void CPUSoftwareInterrupt(int comment)
1745 496
 {
1746
-  static bool disableMessage = false;
1747
-  if(armState) comment >>= 16;
1748
-#ifdef BKPT_SUPPORT
1749
-  if(comment == 0xff) {
1750
-    dbgOutput(NULL, reg[0].I);
1751
-    return;
1752
-  }
1753
-#endif
1754
-#ifdef PROFILING
1755
-  if(comment == 0xfe) {
1756
-    profStartup(reg[0].I, reg[1].I);
1757
-    return;
1758
-  }
1759
-  if(comment == 0xfd) {
1760
-    profControl(reg[0].I);
1761
-    return;
1762
-  }
1763
-  if(comment == 0xfc) {
1764
-    profCleanup();
1765
-    return;
1766
-  }
1767
-  if(comment == 0xfb) {
1768
-    profCount();
1769
-    return;
1770
-  }
1771
-#endif
1772
-  if(comment == 0xfa) {
1773
-    //agbPrintFlush();
1774
-    return;
1775
-  }
1776
-#ifdef SDL
1777
-  if(comment == 0xf9) {
1778
-    emulating = 0;
1779
-    cpuNextEvent = cpuTotalTicks;
1780
-    cpuBreakLoop = true;
1781
-    return;
1782
-  }
1783
-#endif
1784
-  if(useBios) {
1785
-#ifdef GBA_LOGGING
1786
-    if(systemVerbose & VERBOSE_SWI) {
1787
-      log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
1788
-          armState ? armNextPC - 4: armNextPC -2,
1789
-          reg[0].I,
1790
-          reg[1].I,
1791
-          reg[2].I,
1792
-          VCOUNT);
1793
-    }
1794
-#endif
1795
-    CPUSoftwareInterrupt();
1796
-    return;
1797
-  }
1798
-  // This would be correct, but it causes problems if uncommented
1799
-  //  else {
1800
-  //    biosProtected = 0xe3a02004;
1801
-  //  }
1802
-
1803
-  switch(comment) {
1804
-  case 0x00:
1805
-    BIOS_SoftReset();
1806
-    ARM_PREFETCH;
1807
-    break;
1808
-  case 0x01:
1809
-    BIOS_RegisterRamReset();
1810
-    break;
1811
-  case 0x02:
1812
-#ifdef GBA_LOGGING
1813
-    if(systemVerbose & VERBOSE_SWI) {
1814
-      /*log("Halt: (VCOUNT = %2d)\n",
1815
-          VCOUNT);*/
1816
-    }
1817
-#endif
1818
-    holdState = true;
1819
-    holdType = -1;
1820
-    cpuNextEvent = cpuTotalTicks;
1821
-    break;
1822
-  case 0x03:
1823
-#ifdef GBA_LOGGING
1824
-    if(systemVerbose & VERBOSE_SWI) {
1825
-      /*log("Stop: (VCOUNT = %2d)\n",
1826
-          VCOUNT);*/
1827
-    }
1828
-#endif
1829
-    /*holdState = true;
1830
-    holdType = -1;
1831
-    stopState = true;
1832
-    cpuNextEvent = cpuTotalTicks;*/
1833
-    break;
1834
-  case 0x04:
1835
-#ifdef GBA_LOGGING
1836
-    if(systemVerbose & VERBOSE_SWI) {
1837
-      log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n",
1838
-          reg[0].I,
1839
-          reg[1].I,
1840
-          VCOUNT);
1841
-    }
1842
-#endif
1843
-    CPUSoftwareInterrupt();
1844
-    break;
1845
-  case 0x05:
1846
-#ifdef GBA_LOGGING
1847
-    if(systemVerbose & VERBOSE_SWI) {
1848
-      log("VBlankIntrWait: (VCOUNT = %2d)\n",
1849
-          VCOUNT);
1850
-    }
1851
-#endif
1852
-    CPUSoftwareInterrupt();
1853
-    break;
1854
-  case 0x06:
1855
-    CPUSoftwareInterrupt();
1856
-    break;
1857
-  case 0x07:
1858
-    CPUSoftwareInterrupt();
1859
-    break;
1860
-  case 0x08:
1861
-    BIOS_Sqrt();
1862
-    break;
1863
-  case 0x09:
1864
-    BIOS_ArcTan();
1865
-    break;
1866
-  case 0x0A:
1867
-    BIOS_ArcTan2();
1868
-    break;
1869
-  case 0x0B:
1870
-    {
1871
-      int len = (reg[2].I & 0x1FFFFF) >>1;
1872
-      if (!(((reg[0].I & 0xe000000) == 0) ||
1873
-         ((reg[0].I + len) & 0xe000000) == 0))
1874
-      {
1875
-        if ((reg[2].I >> 24) & 1)
1876
-        {
1877
-          if ((reg[2].I >> 26) & 1)
1878
-          SWITicks = (7 + memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1);
1879
-          else
1880
-          SWITicks = (8 + memoryWait[(reg[1].I>>24) & 0xF]) * (len);
1881
-        }
1882
-        else
1883
-        {
1884
-          if ((reg[2].I >> 26) & 1)
1885
-          SWITicks = (10 + memoryWait32[(reg[0].I>>24) & 0xF] +
1886
-              memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1);
1887
-          else
1888
-          SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] +
1889
-              memoryWait[(reg[1].I>>24) & 0xF]) * len;
1890
-        }
1891
-      }
1892
-    }
1893
-    BIOS_CpuSet();
1894
-    break;
1895
-  case 0x0C:
1896
-    {
1897
-      int len = (reg[2].I & 0x1FFFFF) >>5;
1898
-      if (!(((reg[0].I & 0xe000000) == 0) ||
1899
-         ((reg[0].I + len) & 0xe000000) == 0))
1900
-      {
1901
-        if ((reg[2].I >> 24) & 1)
1902
-          SWITicks = (6 + memoryWait32[(reg[1].I>>24) & 0xF] +
1903
-              7 * (memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 1)) * len;
1904
-        else
1905
-          SWITicks = (9 + memoryWait32[(reg[0].I>>24) & 0xF] +
1906
-              memoryWait32[(reg[1].I>>24) & 0xF] +
1907
-              7 * (memoryWaitSeq32[(reg[0].I>>24) & 0xF] +
1908
-              memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 2)) * len;
1909
-      }
1910
-    }
1911
-    BIOS_CpuFastSet();
1912
-    break;
1913
-  case 0x0D:
1914
-    BIOS_GetBiosChecksum();
1915
-    break;
1916
-  case 0x0E:
1917
-    BIOS_BgAffineSet();
1918
-    break;
1919
-  case 0x0F:
1920
-    BIOS_ObjAffineSet();
1921
-    break;
1922
-  case 0x10:
1923
-    {
1924
-      int len = CPUReadHalfWord(reg[2].I);
1925
-      if (!(((reg[0].I & 0xe000000) == 0) ||
1926
-         ((reg[0].I + len) & 0xe000000) == 0))
1927
-        SWITicks = (32 + memoryWait[(reg[0].I>>24) & 0xF]) * len;
1928
-    }
1929
-    BIOS_BitUnPack();
1930
-    break;
1931
-  case 0x11:
1932
-    {
1933
-      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1934
-      if(!(((reg[0].I & 0xe000000) == 0) ||
1935
-          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1936
-        SWITicks = (9 + memoryWait[(reg[1].I>>24) & 0xF]) * len;
1937
-    }
1938
-    BIOS_LZ77UnCompWram();
1939
-    break;
1940
-  case 0x12:
1941
-    {
1942
-      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1943
-      if(!(((reg[0].I & 0xe000000) == 0) ||
1944
-          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1945
-        SWITicks = (19 + memoryWait[(reg[1].I>>24) & 0xF]) * len;
1946
-    }
1947
-    BIOS_LZ77UnCompVram();
1948
-    break;
1949
-  case 0x13:
1950
-    {
1951
-      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1952
-      if(!(((reg[0].I & 0xe000000) == 0) ||
1953
-          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1954
-        SWITicks = (29 + (memoryWait[(reg[0].I>>24) & 0xF]<<1)) * len;
1955
-    }
1956
-    BIOS_HuffUnComp();
1957
-    break;
1958
-  case 0x14:
1959
-    {
1960
-      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1961
-      if(!(((reg[0].I & 0xe000000) == 0) ||
1962
-          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1963
-        SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] +
1964
-          memoryWait[(reg[1].I>>24) & 0xF]) * len;
1965
-    }
1966
-    BIOS_RLUnCompWram();
1967
-    break;
1968
-  case 0x15:
1969
-    {
1970
-      uint32_t len = CPUReadMemory(reg[0].I) >> 9;
1971
-      if(!(((reg[0].I & 0xe000000) == 0) ||
1972
-          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1973
-        SWITicks = (34 + (memoryWait[(reg[0].I>>24) & 0xF] << 1) +
1974
-          memoryWait[(reg[1].I>>24) & 0xF]) * len;
1975
-    }
1976
-    BIOS_RLUnCompVram();
1977
-    break;
1978
-  case 0x16:
1979
-    {
1980
-      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1981
-      if(!(((reg[0].I & 0xe000000) == 0) ||
1982
-          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1983
-        SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] +
1984
-          memoryWait[(reg[1].I>>24) & 0xF]) * len;
1985
-    }
1986
-    BIOS_Diff8bitUnFilterWram();
1987
-    break;
1988
-  case 0x17:
1989
-    {
1990
-      uint32_t len = CPUReadMemory(reg[0].I) >> 9;
1991
-      if(!(((reg[0].I & 0xe000000) == 0) ||
1992
-          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1993
-        SWITicks = (39 + (memoryWait[(reg[0].I>>24) & 0xF]<<1) +
1994
-          memoryWait[(reg[1].I>>24) & 0xF]) * len;
1995
-    }
1996
-    BIOS_Diff8bitUnFilterVram();
1997
-    break;
1998
-  case 0x18:
1999
-    {
2000
-      uint32_t len = CPUReadMemory(reg[0].I) >> 9;
2001
-      if(!(((reg[0].I & 0xe000000) == 0) ||
2002
-          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
2003
-        SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] +
2004
-          memoryWait[(reg[1].I>>24) & 0xF]) * len;
2005
-    }
2006
-    BIOS_Diff16bitUnFilter();
2007
-    break;
2008
-  case 0x19:
2009
-#ifdef GBA_LOGGING
2010
-    if(systemVerbose & VERBOSE_SWI) {
2011
-      log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n",
2012
-          reg[0].I,
2013
-          VCOUNT);
2014
-    }
2015
-#endif
2016
-    if(reg[0].I)
2017
-      soundPause();
2018
-    else
2019
-      soundResume();
2020
-    break;
2021
-  case 0x1F:
2022
-    BIOS_MidiKey2Freq();
2023
-    break;
2024
-  case 0x2A:
2025
-    BIOS_SndDriverJmpTableCopy();
2026
-    // let it go, because we don't really emulate this function
2027
-  default:
2028
-#ifdef GBA_LOGGING
2029
-    if(systemVerbose & VERBOSE_SWI) {
2030
-      log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
2031
-          armState ? armNextPC - 4: armNextPC -2,
2032
-          reg[0].I,
2033
-          reg[1].I,
2034
-          reg[2].I,
2035
-          VCOUNT);
2036
-    }
2037
-#endif
2038
-
2039
-    if(!disableMessage) {
2040
-      /*systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION,
2041
-                    N_("Unsupported BIOS function %02x called from %08x. A BIOS file is needed in order to get correct behaviour."),
2042
-                    comment,
2043
-                    armMode ? armNextPC - 4: armNextPC - 2);*/
2044
-      disableMessage = true;
2045
-    }
2046
-    break;
2047
-  }
497
+	if (armState)
498
+		comment >>= 16;
499
+	if (comment == 0xfa)
500
+		return;
501
+	// This would be correct, but it causes problems if uncommented
502
+	//else
503
+		//biosProtected = 0xe3a02004;
504
+
505
+	switch (comment)
506
+	{
507
+		case 0x00:
508
+			BIOS_SoftReset();
509
+			ARM_PREFETCH();
510
+			break;
511
+		case 0x01:
512
+			BIOS_RegisterRamReset();
513
+			break;
514
+		case 0x02:
515
+			holdState = true;
516
+			holdType = -1;
517
+			cpuNextEvent = cpuTotalTicks;
518
+			break;
519
+		case 0x03:
520
+			break;
521
+		case 0x04:
522
+		case 0x05:
523
+		case 0x06:
524
+		case 0x07:
525
+			CPUSoftwareInterrupt();
526
+			break;
527
+		case 0x08:
528
+			BIOS_Sqrt();
529
+			break;
530
+		case 0x09:
531
+			BIOS_ArcTan();
532
+			break;
533
+		case 0x0A:
534
+			BIOS_ArcTan2();
535
+			break;
536
+		case 0x0B:
537
+		{
538
+			int len = (reg[2].I & 0x1FFFFF) >> 1;
539
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
540
+			{
541
+				if ((reg[2].I >> 24) & 1)
542
+				{
543
+					if ((reg[2].I >> 26) & 1)
544
+						SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1);
545
+					else
546
+						SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * (len);
547
+				}
548
+				else
549
+				{
550
+					if ((reg[2].I >> 26) & 1)
551
+						SWITicks = (10 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1);
552
+					else
553
+						SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
554
+				}
555
+			}
556
+			BIOS_CpuSet();
557
+			break;
558
+		}
559
+		case 0x0C:
560
+		{
561
+			int len = (reg[2].I & 0x1FFFFF) >> 5;
562
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
563
+			{
564
+				if ((reg[2].I >> 24) & 1)
565
+					SWITicks = (6 + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 1)) * len;
566
+				else
567
+					SWITicks = (9 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[0].I >> 24) & 0xF] + memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 2)) * len;
568
+			}
569
+			BIOS_CpuFastSet();
570
+			break;
571
+		}
572
+		case 0x0D:
573
+			BIOS_GetBiosChecksum();
574
+			break;
575
+		case 0x0E:
576
+			BIOS_BgAffineSet();
577
+			break;
578
+		case 0x0F:
579
+			BIOS_ObjAffineSet();
580
+			break;
581
+		case 0x10:
582
+		{
583
+			int len = CPUReadHalfWord(reg[2].I);
584
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000)))
585
+				SWITicks = (32 + memoryWait[(reg[0].I >> 24) & 0xF]) * len;
586
+			BIOS_BitUnPack();
587
+			break;
588
+		}
589
+		case 0x11:
590
+		{
591
+			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
592
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
593
+				SWITicks = (9 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
594
+			BIOS_LZ77UnCompWram();
595
+			break;
596
+		}
597
+		case 0x12:
598
+		{
599
+			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
600
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
601
+				SWITicks = (19 + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
602
+			BIOS_LZ77UnCompVram();
603
+			break;
604
+		}
605
+		case 0x13:
606
+		{
607
+			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
608
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
609
+				SWITicks = (29 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1)) * len;
610
+			BIOS_HuffUnComp();
611
+			break;
612
+		}
613
+		case 0x14:
614
+		{
615
+			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
616
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
617
+				SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
618
+			BIOS_RLUnCompWram();
619
+			break;
620
+		}
621
+		case 0x15:
622
+		{
623
+			uint32_t len = CPUReadMemory(reg[0].I) >> 9;
624
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
625
+				SWITicks = (34 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
626
+			BIOS_RLUnCompVram();
627
+			break;
628
+		}
629
+		case 0x16:
630
+		{
631
+			uint32_t len = CPUReadMemory(reg[0].I) >> 8;
632
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
633
+				SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
634
+			BIOS_Diff8bitUnFilterWram();
635
+			break;
636
+		}
637
+		case 0x17:
638
+		{
639
+			uint32_t len = CPUReadMemory(reg[0].I) >> 9;
640
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
641
+				SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF]<<1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
642
+			BIOS_Diff8bitUnFilterVram();
643
+			break;
644
+		}
645
+		case 0x18:
646
+		{
647
+			uint32_t len = CPUReadMemory(reg[0].I) >> 9;
648
+			if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000)))
649
+				SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len;
650
+			BIOS_Diff16bitUnFilter();
651
+			break;
652
+		}
653
+		case 0x19:
654
+			if (reg[0].I)
655
+				soundPause();
656
+			else
657
+				soundResume();
658
+			break;
659
+		case 0x1F:
660
+			BIOS_MidiKey2Freq();
661
+			break;
662
+		case 0x2A:
663
+			BIOS_SndDriverJmpTableCopy();
664
+			// let it go, because we don't really emulate this function
665
+	}
2048 666
 }
2049 667
 
2050 668
 void CPUCompareVCOUNT()
2051 669
 {
2052
-  if(VCOUNT == (DISPSTAT >> 8)) {
2053
-    DISPSTAT |= 4;
2054
-    UPDATE_REG(0x04, DISPSTAT);
2055
-
2056
-    if(DISPSTAT & 0x20) {
2057
-      IF |= 4;
2058
-      UPDATE_REG(0x202, IF);
2059
-    }
2060
-  } else {
2061
-    DISPSTAT &= 0xFFFB;
2062
-    UPDATE_REG(0x4, DISPSTAT);
2063
-  }
2064
-  if (layerEnableDelay>0)
2065
-  {
2066
-      layerEnableDelay--;
2067
-      if (layerEnableDelay==1)
2068
-          layerEnable = layerSettings & DISPCNT;
2069
-  }
670
+	if (VCOUNT == (DISPSTAT >> 8))
671
+	{
672
+		DISPSTAT |= 4;
673
+		UPDATE_REG(0x04, DISPSTAT);
2070 674
 
675
+		if (DISPSTAT & 0x20)
676
+		{
677
+			IF |= 4;
678
+			UPDATE_REG(0x202, IF);
679
+		}
680
+	}
681
+	else
682
+	{
683
+		DISPSTAT &= 0xFFFB;
684
+		UPDATE_REG(0x4, DISPSTAT);
685
+	}
686
+	if (layerEnableDelay > 0)
687
+	{
688
+		--layerEnableDelay;
689
+		if (layerEnableDelay == 1)
690
+			layerEnable = layerSettings & DISPCNT;
691
+	}
2071 692
 }
2072 693
 
2073 694
 void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int transfer32)
2074 695
 {
2075
-  int sm = s >> 24;
2076
-  int dm = d >> 24;
2077
-  int sw = 0;
2078
-  int dw = 0;
2079
-  int sc = c;
2080
-
2081
-  cpuDmaCount = c;
2082
-  // This is done to get the correct waitstates.
2083
-  if (sm>15)
2084
-      sm=15;
2085
-  if (dm>15)
2086
-      dm=15;
2087
-
2088
-  //if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07))
2089
-  //    blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ?  true : false);
2090
-
2091
-  if(transfer32) {
2092
-    s &= 0xFFFFFFFC;
2093
-    if(s < 0x02000000 && (reg[15].I >> 24)) {
2094
-      while(c != 0) {
2095
-        CPUWriteMemory(d, 0);
2096
-        d += di;
2097
-        c--;
2098
-      }
2099
-    } else {
2100
-      while(c != 0) {
2101
-        cpuDmaLast = CPUReadMemory(s);
2102
-        CPUWriteMemory(d, cpuDmaLast);
2103
-        d += di;
2104
-        s += si;
2105
-        c--;
2106
-      }
2107
-    }
2108
-  } else {
2109
-    s &= 0xFFFFFFFE;
2110
-    si = (int)si >> 1;
2111
-    di = (int)di >> 1;
2112
-    if(s < 0x02000000 && (reg[15].I >> 24)) {
2113
-      while(c != 0) {
2114
-        CPUWriteHalfWord(d, 0);
2115
-        d += di;
2116
-        c--;
2117
-      }
2118
-    } else {
2119
-      while(c != 0) {
2120
-        cpuDmaLast = CPUReadHalfWord(s);
2121
-        CPUWriteHalfWord(d, cpuDmaLast);
2122
-        cpuDmaLast |= (cpuDmaLast<<16);
2123
-        d += di;
2124
-        s += si;
2125
-        c--;
2126
-      }
2127
-    }
2128
-  }
2129
-
2130
-  cpuDmaCount = 0;
2131
-
2132
-  int totalTicks = 0;
2133
-
2134
-  if(transfer32) {
2135
-      sw =1+memoryWaitSeq32[sm & 15];
2136
-      dw =1+memoryWaitSeq32[dm & 15];
2137
-      totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait32[sm & 15] +
2138
-          memoryWaitSeq32[dm & 15];
2139
-  }
2140
-  else
2141
-  {
2142
-     sw = 1+memoryWaitSeq[sm & 15];
2143
-     dw = 1+memoryWaitSeq[dm & 15];
2144
-      totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait[sm & 15] +
2145
-          memoryWaitSeq[dm & 15];
2146
-  }
2147
-
2148
-  cpuDmaTicksToUpdate += totalTicks;
696
+	int sm = s >> 24;
697
+	int dm = d >> 24;
698
+	int sw = 0;
699
+	int dw = 0;
700
+	int sc = c;
701
+
702
+	// This is done to get the correct waitstates.
703
+	if (sm > 15)
704
+		sm = 15;
705
+	if (dm > 15)
706
+		dm = 15;
707
+
708
+	if (transfer32)
709
+	{
710
+		s &= 0xFFFFFFFC;
711
+		if (s < 0x02000000 && (reg[15].I >> 24))
712
+		{
713
+			while (c)
714
+			{
715
+				CPUWriteMemory(d, 0);
716
+				d += di;
717
+				--c;
718
+			}
719
+		}
720
+		else
721
+		{
722
+			while (c)
723
+			{
724
+				cpuDmaLast = CPUReadMemory(s);
725
+				CPUWriteMemory(d, cpuDmaLast);
726
+				d += di;
727
+				s += si;
728
+				--c;
729
+			}
730
+		}
731
+	}
732
+	else
733
+	{
734
+		s &= 0xFFFFFFFE;
735
+		si = static_cast<int>(si) >> 1;
736
+		di = static_cast<int>(di) >> 1;
737
+		if (s < 0x02000000 && (reg[15].I >> 24))
738
+		{
739
+			while (c)
740
+			{
741
+				CPUWriteHalfWord(d, 0);
742
+				d += di;
743
+				--c;
744
+			}
745
+		}
746
+		else
747
+		{
748
+			while (c)
749
+			{
750
+				cpuDmaLast = CPUReadHalfWord(s);
751
+				CPUWriteHalfWord(d, cpuDmaLast);
752
+				cpuDmaLast |= cpuDmaLast << 16;
753
+				d += di;
754
+				s += si;
755
+				--c;
756
+			}
757
+		}
758
+	}
2149 759
 
760
+	int totalTicks = 0;
761
+
762
+	if (transfer32)
763
+	{
764
+		sw = 1 + memoryWaitSeq32[sm & 15];
765
+		dw = 1 + memoryWaitSeq32[dm & 15];
766
+		totalTicks = (sw + dw) * (sc - 1) + 6 + memoryWait32[sm & 15] + memoryWaitSeq32[dm & 15];
767
+	}
768
+	else
769
+	{
770
+		sw = 1 + memoryWaitSeq[sm & 15];
771
+		dw = 1 + memoryWaitSeq[dm & 15];
772
+		totalTicks = (sw + dw) * (sc - 1) + 6 + memoryWait[sm & 15] + memoryWaitSeq[dm & 15];
773
+	}
774
+
775
+	cpuDmaTicksToUpdate += totalTicks;
2150 776
 }
2151 777
 
2152 778
 void CPUCheckDMA(int reason, int dmamask)
2153 779
 {
2154
-  // DMA 0
2155
-  if((DM0CNT_H & 0x8000) && (dmamask & 1)) {
2156
-    if(((DM0CNT_H >> 12) & 3) == reason) {
2157
-      uint32_t sourceIncrement = 4;
2158
-      uint32_t destIncrement = 4;
2159
-      switch((DM0CNT_H >> 7) & 3) {
2160
-      case 0:
2161
-        break;
2162
-      case 1:
2163
-        sourceIncrement = (uint32_t)-4;
2164
-        break;
2165
-      case 2:
2166
-        sourceIncrement = 0;
2167
-        break;
2168
-      }
2169
-      switch((DM0CNT_H >> 5) & 3) {
2170
-      case 0:
2171
-        break;
2172
-      case 1:
2173
-        destIncrement = (uint32_t)-4;
2174
-        break;
2175
-      case 2:
2176
-        destIncrement = 0;
2177
-        break;
2178
-      }
2179
-#ifdef GBA_LOGGING
2180
-      if(systemVerbose & VERBOSE_DMA0) {
2181
-        int count = (DM0CNT_L ? DM0CNT_L : 0x4000) << 1;
2182
-        if(DM0CNT_H & 0x0400)
2183
-          count <<= 1;
2184
-        log("DMA0: s=%08x d=%08x c=%04x count=%08x\n", dma0Source, dma0Dest,
2185
-            DM0CNT_H,
2186
-            count);
2187
-      }
2188
-#endif
2189
-      doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement,
2190
-            DM0CNT_L ? DM0CNT_L : 0x4000,
2191
-            DM0CNT_H & 0x0400);
2192
-
2193
-      if(DM0CNT_H & 0x4000) {
2194
-        IF |= 0x0100;
2195
-        UPDATE_REG(0x202, IF);
2196
-        cpuNextEvent = cpuTotalTicks;
2197
-      }
2198
-
2199
-      if(((DM0CNT_H >> 5) & 3) == 3) {
2200
-        dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
2201
-      }
2202
-
2203
-      if(!(DM0CNT_H & 0x0200) || (reason == 0)) {
2204
-        DM0CNT_H &= 0x7FFF;
2205
-        UPDATE_REG(0xBA, DM0CNT_H);
2206
-      }
2207
-    }
2208
-  }
2209
-
2210
-  // DMA 1
2211
-  if((DM1CNT_H & 0x8000) && (dmamask & 2)) {
2212
-    if(((DM1CNT_H >> 12) & 3) == reason) {
2213
-      uint32_t sourceIncrement = 4;
2214
-      uint32_t destIncrement = 4;
2215
-      switch((DM1CNT_H >> 7) & 3) {
2216
-      case 0:
2217
-        break;
2218
-      case 1:
2219
-        sourceIncrement = (uint32_t)-4;
2220
-        break;
2221
-      case 2:
2222
-        sourceIncrement = 0;
2223
-        break;
2224
-      }
2225
-      switch((DM1CNT_H >> 5) & 3) {
2226
-      case 0:
2227
-        break;
2228
-      case 1:
2229
-        destIncrement = (uint32_t)-4;
2230
-        break;
2231
-      case 2:
2232
-        destIncrement = 0;
2233
-        break;
2234
-      }
2235
-      if(reason == 3) {
2236
-#ifdef GBA_LOGGING
2237
-        if(systemVerbose & VERBOSE_DMA1) {
2238
-          log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
2239
-              DM1CNT_H,
2240
-              16);
2241
-        }
2242
-#endif
2243
-        doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4,
2244
-              0x0400);
2245
-      } else {
2246
-#ifdef GBA_LOGGING
2247
-        if(systemVerbose & VERBOSE_DMA1) {
2248
-          int count = (DM1CNT_L ? DM1CNT_L : 0x4000) << 1;
2249
-          if(DM1CNT_H & 0x0400)
2250
-            count <<= 1;
2251
-          log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
2252
-              DM1CNT_H,
2253
-              count);
2254
-        }
2255
-#endif
2256
-        doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement,
2257
-              DM1CNT_L ? DM1CNT_L : 0x4000,
2258
-              DM1CNT_H & 0x0400);
2259
-      }
2260
-
2261
-      if(DM1CNT_H & 0x4000) {
2262
-        IF |= 0x0200;
2263
-        UPDATE_REG(0x202, IF);
2264
-        cpuNextEvent = cpuTotalTicks;
2265
-      }
2266
-
2267
-      if(((DM1CNT_H >> 5) & 3) == 3) {
2268
-        dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
2269
-      }
2270
-
2271
-      if(!(DM1CNT_H & 0x0200) || (reason == 0)) {
2272
-        DM1CNT_H &= 0x7FFF;
2273
-        UPDATE_REG(0xC6, DM1CNT_H);
2274
-      }
2275
-    }
2276
-  }
2277
-
2278
-  // DMA 2
2279
-  if((DM2CNT_H & 0x8000) && (dmamask & 4)) {
2280
-    if(((DM2CNT_H >> 12) & 3) == reason) {
2281
-      uint32_t sourceIncrement = 4;
2282
-      uint32_t destIncrement = 4;
2283
-      switch((DM2CNT_H >> 7) & 3) {
2284
-      case 0:
2285
-        break;
2286
-      case 1:
2287
-        sourceIncrement = (uint32_t)-4;
2288
-        break;
2289
-      case 2:
2290
-        sourceIncrement = 0;
2291
-        break;
2292
-      }
2293
-      switch((DM2CNT_H >> 5) & 3) {
2294
-      case 0:
2295
-        break;
2296
-      case 1:
2297
-        destIncrement = (uint32_t)-4;
2298
-        break;
2299
-      case 2:
2300
-        destIncrement = 0;
2301
-        break;
2302
-      }
2303
-      if(reason == 3) {
2304
-#ifdef GBA_LOGGING
2305
-        if(systemVerbose & VERBOSE_DMA2) {
2306
-          int count = (4) << 2;
2307
-          log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
2308
-              DM2CNT_H,
2309
-              count);
2310
-        }
2311
-#endif
2312
-        doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4,
2313
-              0x0400);
2314
-      } else {
2315
-#ifdef GBA_LOGGING
2316
-        if(systemVerbose & VERBOSE_DMA2) {
2317
-          int count = (DM2CNT_L ? DM2CNT_L : 0x4000) << 1;
2318
-          if(DM2CNT_H & 0x0400)
2319
-            count <<= 1;
2320
-          log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
2321
-              DM2CNT_H,
2322
-              count);
2323
-        }
2324
-#endif
2325
-        doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement,
2326
-              DM2CNT_L ? DM2CNT_L : 0x4000,
2327
-              DM2CNT_H & 0x0400);
2328
-      }
2329
-
2330
-      if(DM2CNT_H & 0x4000) {
2331
-        IF |= 0x0400;
2332
-        UPDATE_REG(0x202, IF);
2333
-        cpuNextEvent = cpuTotalTicks;
2334
-      }
2335
-
2336
-      if(((DM2CNT_H >> 5) & 3) == 3) {
2337
-        dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
2338
-      }
2339
-
2340
-      if(!(DM2CNT_H & 0x0200) || (reason == 0)) {
2341
-        DM2CNT_H &= 0x7FFF;
2342
-        UPDATE_REG(0xD2, DM2CNT_H);
2343
-      }
2344
-    }
2345
-  }
2346
-
2347
-  // DMA 3
2348
-  if((DM3CNT_H & 0x8000) && (dmamask & 8)) {
2349
-    if(((DM3CNT_H >> 12) & 3) == reason) {
2350
-      uint32_t sourceIncrement = 4;
2351
-      uint32_t destIncrement = 4;
2352
-      switch((DM3CNT_H >> 7) & 3) {
2353
-      case 0:
2354
-        break;
2355
-      case 1:
2356
-        sourceIncrement = (uint32_t)-4;
2357
-        break;
2358
-      case 2:
2359
-        sourceIncrement = 0;
2360
-        break;
2361
-      }
2362
-      switch((DM3CNT_H >> 5) & 3) {
2363
-      case 0:
2364
-        break;
2365
-      case 1:
2366
-        destIncrement = (uint32_t)-4;
2367
-        break;
2368
-      case 2:
2369
-        destIncrement = 0;
2370
-        break;
2371
-      }
2372
-#ifdef GBA_LOGGING
2373
-      if(systemVerbose & VERBOSE_DMA3) {
2374
-        int count = (DM3CNT_L ? DM3CNT_L : 0x10000) << 1;
2375
-        if(DM3CNT_H & 0x0400)
2376
-          count <<= 1;
2377
-        log("DMA3: s=%08x d=%08x c=%04x count=%08x\n", dma3Source, dma3Dest,
2378
-            DM3CNT_H,
2379
-            count);
2380
-      }
2381
-#endif
2382
-      doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement,
2383
-            DM3CNT_L ? DM3CNT_L : 0x10000,
2384
-            DM3CNT_H & 0x0400);
2385
-      if(DM3CNT_H & 0x4000) {
2386
-        IF |= 0x0800;
2387
-        UPDATE_REG(0x202, IF);
2388
-        cpuNextEvent = cpuTotalTicks;
2389
-      }
2390
-
2391
-      if(((DM3CNT_H >> 5) & 3) == 3) {
2392
-        dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
2393
-      }
2394
-
2395
-      if(!(DM3CNT_H & 0x0200) || (reason == 0)) {
2396
-        DM3CNT_H &= 0x7FFF;
2397
-        UPDATE_REG(0xDE, DM3CNT_H);
2398
-      }
2399
-    }
2400
-  }
780
+	// DMA 0
781
+	if ((DM0CNT_H & 0x8000) && (dmamask & 1))
782
+	{
783
+		if (((DM0CNT_H >> 12) & 3) == reason)
784
+		{
785
+			uint32_t sourceIncrement = 4;
786
+			uint32_t destIncrement = 4;
787
+			switch ((DM0CNT_H >> 7) & 3)
788
+			{
789
+				case 0:
790
+					break;
791
+				case 1:
792
+					sourceIncrement = static_cast<uint32_t>(-4);
793
+					break;
794
+				case 2:
795
+					sourceIncrement = 0;
796
+			}
797
+			switch ((DM0CNT_H >> 5) & 3)
798
+			{
799
+				case 0:
800
+					break;
801
+				case 1:
802
+					destIncrement = static_cast<uint32_t>(-4);
803
+					break;
804
+				case 2:
805
+					destIncrement = 0;
806
+			}
807
+			doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, DM0CNT_L ? DM0CNT_L : 0x4000, DM0CNT_H & 0x0400);
808
+
809
+			if (DM0CNT_H & 0x4000)
810
+			{
811
+				IF |= 0x0100;
812
+				UPDATE_REG(0x202, IF);
813
+				cpuNextEvent = cpuTotalTicks;
814
+			}
815
+
816
+			if (((DM0CNT_H >> 5) & 3) == 3)
817
+				dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
818
+
819
+			if (!(DM0CNT_H & 0x0200) || !reason)
820
+			{
821
+				DM0CNT_H &= 0x7FFF;
822
+				UPDATE_REG(0xBA, DM0CNT_H);
823
+			}
824
+		}
825
+	}
826
+
827
+	// DMA 1
828
+	if ((DM1CNT_H & 0x8000) && (dmamask & 2))
829
+	{
830
+		if (((DM1CNT_H >> 12) & 3) == reason)
831
+		{
832
+			uint32_t sourceIncrement = 4;
833
+			uint32_t destIncrement = 4;
834
+			switch ((DM1CNT_H >> 7) & 3)
835
+			{
836
+				case 0:
837
+					break;
838
+				case 1:
839
+					sourceIncrement = static_cast<uint32_t>(-4);
840
+					break;
841
+				case 2:
842
+					sourceIncrement = 0;
843
+			}
844
+			switch ((DM1CNT_H >> 5) & 3)
845
+			{
846
+				case 0:
847
+					break;
848
+				case 1:
849
+					destIncrement = static_cast<uint32_t>(-4);
850
+					break;
851
+				case 2:
852
+					destIncrement = 0;
853
+			}
854
+			if (reason == 3)
855
+				doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, 0x0400);
856
+			else
857
+				doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, DM1CNT_L ? DM1CNT_L : 0x4000, DM1CNT_H & 0x0400);
858
+
859
+			if (DM1CNT_H & 0x4000)
860
+			{
861
+				IF |= 0x0200;
862
+				UPDATE_REG(0x202, IF);
863
+				cpuNextEvent = cpuTotalTicks;
864
+			}
865
+
866
+			if (((DM1CNT_H >> 5) & 3) == 3)
867
+				dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
868
+
869
+			if (!(DM1CNT_H & 0x0200) || !reason)
870
+			{
871
+				DM1CNT_H &= 0x7FFF;
872
+				UPDATE_REG(0xC6, DM1CNT_H);
873
+			}
874
+		}
875
+	}
876
+
877
+	// DMA 2
878
+	if ((DM2CNT_H & 0x8000) && (dmamask & 4))
879
+	{
880
+		if (((DM2CNT_H >> 12) & 3) == reason)
881
+		{
882
+			uint32_t sourceIncrement = 4;
883
+			uint32_t destIncrement = 4;
884
+			switch ((DM2CNT_H >> 7) & 3)
885
+			{
886
+				case 0:
887
+					break;
888
+				case 1:
889
+					sourceIncrement = static_cast<uint32_t>(-4);
890
+					break;
891
+				case 2:
892
+					sourceIncrement = 0;
893
+			}
894
+			switch ((DM2CNT_H >> 5) & 3)
895
+			{
896
+				case 0:
897
+					break;
898
+				case 1:
899
+					destIncrement = static_cast<uint32_t>(-4);
900
+					break;
901
+				case 2:
902
+					destIncrement = 0;
903
+			}
904
+			if (reason == 3)
905
+				doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, 0x0400);
906
+			else
907
+				doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, DM2CNT_L ? DM2CNT_L : 0x4000, DM2CNT_H & 0x0400);
908
+
909
+			if (DM2CNT_H & 0x4000)
910
+			{
911
+				IF |= 0x0400;
912
+				UPDATE_REG(0x202, IF);
913
+				cpuNextEvent = cpuTotalTicks;
914
+			}
915
+
916
+			if (((DM2CNT_H >> 5) & 3) == 3)
917
+				dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
918
+
919
+			if (!(DM2CNT_H & 0x0200) || !reason)
920
+			{
921
+				DM2CNT_H &= 0x7FFF;
922
+				UPDATE_REG(0xD2, DM2CNT_H);
923
+			}
924
+		}
925
+	}
926
+
927
+	// DMA 3
928
+	if ((DM3CNT_H & 0x8000) && (dmamask & 8))
929
+	{
930
+		if (((DM3CNT_H >> 12) & 3) == reason)
931
+		{
932
+			uint32_t sourceIncrement = 4;
933
+			uint32_t destIncrement = 4;
934
+			switch ((DM3CNT_H >> 7) & 3)
935
+			{
936
+				case 0:
937
+					break;
938
+				case 1:
939
+					sourceIncrement = static_cast<uint32_t>(-4);
940
+					break;
941
+				case 2:
942
+					sourceIncrement = 0;
943
+			}
944
+			switch ((DM3CNT_H >> 5) & 3)
945
+			{
946
+				case 0:
947
+					break;
948
+				case 1:
949
+					destIncrement = static_cast<uint32_t>(-4);
950
+					break;
951
+				case 2:
952
+					destIncrement = 0;
953
+			}
954
+			doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, DM3CNT_L ? DM3CNT_L : 0x10000, DM3CNT_H & 0x0400);
955
+			if (DM3CNT_H & 0x4000)
956
+			{
957
+				IF |= 0x0800;
958
+				UPDATE_REG(0x202, IF);
959
+				cpuNextEvent = cpuTotalTicks;
960
+			}
961
+
962
+			if (((DM3CNT_H >> 5) & 3) == 3)
963
+				dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
964
+
965
+			if (!(DM3CNT_H & 0x0200) || !reason)
966
+			{
967
+				DM3CNT_H &= 0x7FFF;
968
+				UPDATE_REG(0xDE, DM3CNT_H);
969
+			}
970
+		}
971
+	}
2401 972
 }
2402 973
 
2403 974
 void CPUUpdateRegister(uint32_t address, uint16_t value)
2404 975
 {
2405
-  switch(address)
2406
-  {
2407
-  case 0x00:
2408
-    { // we need to place the following code in { } because we declare & initialize variables in a case statement
2409
-      if((value & 7) > 5) {
2410
-        // display modes above 0-5 are prohibited
2411
-        DISPCNT = (value & 7);
2412
-      }
2413
-      bool change = (0 != ((DISPCNT ^ value) & 0x80));
2414
-      bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00));
2415
-      uint16_t changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated
2416
-
2417
-      DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode
2418
-      UPDATE_REG(0x00, DISPCNT);
2419
-
2420
-      if(changeBGon) {
2421
-        layerEnableDelay = 4;
2422
-        layerEnable = layerSettings & value & (~changeBGon);
2423
-      } else {
2424
-        layerEnable = layerSettings & value;
2425
-        // CPUUpdateTicks();
2426
-      }
2427
-
2428
-      windowOn = (layerEnable & 0x6000) ? true : false;
2429
-      if(change && !((value & 0x80))) {
2430
-        if(!(DISPSTAT & 1)) {
2431
-          lcdTicks = 1008;
2432
-          //      VCOUNT = 0;
2433
-          //      UPDATE_REG(0x06, VCOUNT);
2434
-          DISPSTAT &= 0xFFFC;
2435
-          UPDATE_REG(0x04, DISPSTAT);
2436
-          CPUCompareVCOUNT();
2437
-        }
2438
-        //        (*renderLine)();
2439
-      }
2440
-      //CPUUpdateRender();
2441
-      // we only care about changes in BG0-BG3
2442
-      if(changeBG) {
2443
-        //CPUUpdateRenderBuffers(false);
2444
-      }
2445
-      break;
2446
-    }
2447
-  case 0x04:
2448
-    DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7);
2449
-    UPDATE_REG(0x04, DISPSTAT);
2450
-    break;
2451
-  case 0x06:
2452
-    // not writable
2453
-    break;
2454
-  case 0x08:
2455
-    BG0CNT = (value & 0xDFCF);
2456
-    UPDATE_REG(0x08, BG0CNT);
2457
-    break;
2458
-  case 0x0A:
2459
-    BG1CNT = (value & 0xDFCF);
2460
-    UPDATE_REG(0x0A, BG1CNT);
2461
-    break;
2462
-  case 0x0C:
2463
-    BG2CNT = (value & 0xFFCF);
2464
-    UPDATE_REG(0x0C, BG2CNT);
2465
-    break;
2466
-  case 0x0E:
2467
-    BG3CNT = (value & 0xFFCF);
2468
-    UPDATE_REG(0x0E, BG3CNT);
2469
-    break;
2470
-  case 0x10:
2471
-    BG0HOFS = value & 511;
2472
-    UPDATE_REG(0x10, BG0HOFS);
2473
-    break;
2474
-  case 0x12:
2475
-    BG0VOFS = value & 511;
2476
-    UPDATE_REG(0x12, BG0VOFS);
2477
-    break;
2478
-  case 0x14:
2479
-    BG1HOFS = value & 511;
2480
-    UPDATE_REG(0x14, BG1HOFS);
2481
-    break;
2482
-  case 0x16:
2483
-    BG1VOFS = value & 511;
2484
-    UPDATE_REG(0x16, BG1VOFS);
2485
-    break;
2486
-  case 0x18:
2487
-    BG2HOFS = value & 511;
2488
-    UPDATE_REG(0x18, BG2HOFS);
2489
-    break;
2490
-  case 0x1A:
2491
-    BG2VOFS = value & 511;
2492
-    UPDATE_REG(0x1A, BG2VOFS);
2493
-    break;
2494
-  case 0x1C:
2495
-    BG3HOFS = value & 511;
2496
-    UPDATE_REG(0x1C, BG3HOFS);
2497
-    break;
2498
-  case 0x1E:
2499
-    BG3VOFS = value & 511;
2500
-    UPDATE_REG(0x1E, BG3VOFS);
2501
-    break;
2502
-  case 0x20:
2503
-    BG2PA = value;
2504
-    UPDATE_REG(0x20, BG2PA);
2505
-    break;
2506
-  case 0x22:
2507
-    BG2PB = value;
2508
-    UPDATE_REG(0x22, BG2PB);
2509
-    break;
2510
-  case 0x24:
2511
-    BG2PC = value;
2512
-    UPDATE_REG(0x24, BG2PC);
2513
-    break;
2514
-  case 0x26:
2515
-    BG2PD = value;
2516
-    UPDATE_REG(0x26, BG2PD);
2517
-    break;
2518
-  case 0x28:
2519
-    BG2X_L = value;
2520
-    UPDATE_REG(0x28, BG2X_L);
2521
-    //gfxBG2Changed |= 1;
2522
-    break;
2523
-  case 0x2A:
2524
-    BG2X_H = (value & 0xFFF);
2525
-    UPDATE_REG(0x2A, BG2X_H);
2526
-    //gfxBG2Changed |= 1;
2527
-    break;
2528
-  case 0x2C:
2529
-    BG2Y_L = value;
2530
-    UPDATE_REG(0x2C, BG2Y_L);
2531
-    //gfxBG2Changed |= 2;
2532
-    break;
2533
-  case 0x2E:
2534
-    BG2Y_H = value & 0xFFF;
2535
-    UPDATE_REG(0x2E, BG2Y_H);
2536
-    //gfxBG2Changed |= 2;
2537
-    break;
2538
-  case 0x30:
2539
-    BG3PA = value;
2540
-    UPDATE_REG(0x30, BG3PA);
2541
-    break;
2542
-  case 0x32:
2543
-    BG3PB = value;
2544
-    UPDATE_REG(0x32, BG3PB);
2545
-    break;
2546
-  case 0x34:
2547
-    BG3PC = value;
2548
-    UPDATE_REG(0x34, BG3PC);
2549
-    break;
2550
-  case 0x36:
2551
-    BG3PD = value;
2552
-    UPDATE_REG(0x36, BG3PD);
2553
-    break;
2554
-  case 0x38:
2555
-    BG3X_L = value;
2556
-    UPDATE_REG(0x38, BG3X_L);
2557
-    //gfxBG3Changed |= 1;
2558
-    break;
2559
-  case 0x3A:
2560
-    BG3X_H = value & 0xFFF;
2561
-    UPDATE_REG(0x3A, BG3X_H);
2562
-    //gfxBG3Changed |= 1;
2563
-    break;
2564
-  case 0x3C:
2565
-    BG3Y_L = value;
2566
-    UPDATE_REG(0x3C, BG3Y_L);
2567
-    //gfxBG3Changed |= 2;
2568
-    break;
2569
-  case 0x3E:
2570
-    BG3Y_H = value & 0xFFF;
2571
-    UPDATE_REG(0x3E, BG3Y_H);
2572
-    //gfxBG3Changed |= 2;
2573
-    break;
2574
-  case 0x40:
2575
-    WIN0H = value;
2576
-    UPDATE_REG(0x40, WIN0H);
2577
-    //CPUUpdateWindow0();
2578
-    break;
2579
-  case 0x42:
2580
-    WIN1H = value;
2581
-    UPDATE_REG(0x42, WIN1H);
2582
-    //CPUUpdateWindow1();
2583
-    break;
2584
-  case 0x44:
2585
-    WIN0V = value;
2586
-    UPDATE_REG(0x44, WIN0V);
2587
-    break;
2588
-  case 0x46:
2589
-    WIN1V = value;
2590
-    UPDATE_REG(0x46, WIN1V);
2591
-    break;
2592
-  case 0x48:
2593
-    WININ = value & 0x3F3F;
2594
-    UPDATE_REG(0x48, WININ);
2595
-    break;
2596
-  case 0x4A:
2597
-    WINOUT = value & 0x3F3F;
2598
-    UPDATE_REG(0x4A, WINOUT);
2599
-    break;
2600
-  case 0x4C:
2601
-    MOSAIC = value;
2602
-    UPDATE_REG(0x4C, MOSAIC);
2603
-    break;
2604
-  case 0x50:
2605
-    BLDMOD = value & 0x3FFF;
2606
-    UPDATE_REG(0x50, BLDMOD);
2607
-    fxOn = ((BLDMOD>>6)&3) != 0;
2608
-    //CPUUpdateRender();
2609
-    break;
2610
-  case 0x52:
2611
-    COLEV = value & 0x1F1F;
2612
-    UPDATE_REG(0x52, COLEV);
2613
-    break;
2614
-  case 0x54:
2615
-    COLY = value & 0x1F;
2616
-    UPDATE_REG(0x54, COLY);
2617
-    break;
2618
-  case 0x60:
2619
-  case 0x62:
2620
-  case 0x64:
2621
-  case 0x68:
2622
-  case 0x6c:
2623
-  case 0x70:
2624
-  case 0x72:
2625
-  case 0x74:
2626
-  case 0x78:
2627
-  case 0x7c:
2628
-  case 0x80:
2629
-  case 0x84:
2630
-    soundEvent(address&0xFF, (uint8_t)(value & 0xFF));
2631
-    soundEvent((address&0xFF)+1, (uint8_t)(value>>8));
2632
-    break;
2633
-  case 0x82:
2634
-  case 0x88:
2635
-  case 0xa0:
2636
-  case 0xa2:
2637
-  case 0xa4:
2638
-  case 0xa6:
2639
-  case 0x90:
2640
-  case 0x92:
2641
-  case 0x94:
2642
-  case 0x96:
2643
-  case 0x98:
2644
-  case 0x9a:
2645
-  case 0x9c:
2646
-  case 0x9e:
2647
-    soundEvent(address&0xFF, value);
2648
-    break;
2649
-  case 0xB0:
2650
-    DM0SAD_L = value;
2651
-    UPDATE_REG(0xB0, DM0SAD_L);
2652
-    break;
2653
-  case 0xB2:
2654
-    DM0SAD_H = value & 0x07FF;
2655
-    UPDATE_REG(0xB2, DM0SAD_H);
2656
-    break;
2657
-  case 0xB4:
2658
-    DM0DAD_L = value;
2659
-    UPDATE_REG(0xB4, DM0DAD_L);
2660
-    break;
2661
-  case 0xB6:
2662
-    DM0DAD_H = value & 0x07FF;
2663
-    UPDATE_REG(0xB6, DM0DAD_H);
2664
-    break;
2665
-  case 0xB8:
2666
-    DM0CNT_L = value & 0x3FFF;
2667
-    UPDATE_REG(0xB8, 0);
2668
-    break;
2669
-  case 0xBA:
2670
-    {
2671
-      bool start = ((DM0CNT_H ^ value) & 0x8000) ? true : false;
2672
-      value &= 0xF7E0;
2673
-
2674
-      DM0CNT_H = value;
2675
-      UPDATE_REG(0xBA, DM0CNT_H);
2676
-
2677
-      if(start && (value & 0x8000)) {
2678
-        dma0Source = DM0SAD_L | (DM0SAD_H << 16);
2679
-        dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
2680
-        CPUCheckDMA(0, 1);
2681
-      }
2682
-    }
2683
-    break;
2684
-  case 0xBC:
2685
-    DM1SAD_L = value;
2686
-    UPDATE_REG(0xBC, DM1SAD_L);
2687
-    break;
2688
-  case 0xBE:
2689
-    DM1SAD_H = value & 0x0FFF;
2690
-    UPDATE_REG(0xBE, DM1SAD_H);
2691
-    break;
2692
-  case 0xC0:
2693
-    DM1DAD_L = value;
2694
-    UPDATE_REG(0xC0, DM1DAD_L);
2695
-    break;
2696
-  case 0xC2:
2697
-    DM1DAD_H = value & 0x07FF;
2698
-    UPDATE_REG(0xC2, DM1DAD_H);
2699
-    break;
2700
-  case 0xC4:
2701
-    DM1CNT_L = value & 0x3FFF;
2702
-    UPDATE_REG(0xC4, 0);
2703
-    break;
2704
-  case 0xC6:
2705
-    {
2706
-      bool start = ((DM1CNT_H ^ value) & 0x8000) ? true : false;
2707
-      value &= 0xF7E0;
2708
-
2709
-      DM1CNT_H = value;
2710
-      UPDATE_REG(0xC6, DM1CNT_H);
2711
-
2712
-      if(start && (value & 0x8000)) {
2713
-        dma1Source = DM1SAD_L | (DM1SAD_H << 16);
2714
-        dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
2715
-        CPUCheckDMA(0, 2);
2716
-      }
2717
-    }
2718
-    break;
2719
-  case 0xC8:
2720
-    DM2SAD_L = value;
2721
-    UPDATE_REG(0xC8, DM2SAD_L);
2722
-    break;
2723
-  case 0xCA:
2724
-    DM2SAD_H = value & 0x0FFF;
2725
-    UPDATE_REG(0xCA, DM2SAD_H);
2726
-    break;
2727
-  case 0xCC:
2728
-    DM2DAD_L = value;
2729
-    UPDATE_REG(0xCC, DM2DAD_L);
2730
-    break;
2731
-  case 0xCE:
2732
-    DM2DAD_H = value & 0x07FF;
2733
-    UPDATE_REG(0xCE, DM2DAD_H);
2734
-    break;
2735
-  case 0xD0:
2736
-    DM2CNT_L = value & 0x3FFF;
2737
-    UPDATE_REG(0xD0, 0);
2738
-    break;
2739
-  case 0xD2:
2740
-    {
2741
-      bool start = ((DM2CNT_H ^ value) & 0x8000) ? true : false;
2742
-
2743
-      value &= 0xF7E0;
2744
-
2745
-      DM2CNT_H = value;
2746
-      UPDATE_REG(0xD2, DM2CNT_H);
2747
-
2748
-      if(start && (value & 0x8000)) {
2749
-        dma2Source = DM2SAD_L | (DM2SAD_H << 16);
2750
-        dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
2751
-
2752
-        CPUCheckDMA(0, 4);
2753
-      }
2754
-    }
2755
-    break;
2756
-  case 0xD4:
2757
-    DM3SAD_L = value;
2758
-    UPDATE_REG(0xD4, DM3SAD_L);
2759
-    break;
2760
-  case 0xD6:
2761
-    DM3SAD_H = value & 0x0FFF;
2762
-    UPDATE_REG(0xD6, DM3SAD_H);
2763
-    break;
2764
-  case 0xD8:
2765
-    DM3DAD_L = value;
2766
-    UPDATE_REG(0xD8, DM3DAD_L);
2767
-    break;
2768
-  case 0xDA:
2769
-    DM3DAD_H = value & 0x0FFF;
2770
-    UPDATE_REG(0xDA, DM3DAD_H);
2771
-    break;
2772
-  case 0xDC:
2773
-    DM3CNT_L = value;
2774
-    UPDATE_REG(0xDC, 0);
2775
-    break;
2776
-  case 0xDE:
2777
-    {
2778
-      bool start = ((DM3CNT_H ^ value) & 0x8000) ? true : false;
2779
-
2780
-      value &= 0xFFE0;
2781
-
2782
-      DM3CNT_H = value;
2783
-      UPDATE_REG(0xDE, DM3CNT_H);
2784
-
2785
-      if(start && (value & 0x8000)) {
2786
-        dma3Source = DM3SAD_L | (DM3SAD_H << 16);
2787
-        dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
2788
-        CPUCheckDMA(0,8);
2789
-      }
2790
-    }
2791
-    break;
2792
-  case 0x100:
2793
-    timer0Reload = value;
2794
-    interp_rate();
2795
-    break;
2796
-  case 0x102:
2797
-    timer0Value = value;
2798
-    timerOnOffDelay|=1;
2799
-    cpuNextEvent = cpuTotalTicks;
2800
-    break;
2801
-  case 0x104:
2802
-    timer1Reload = value;
2803
-    interp_rate();
2804
-    break;
2805
-  case 0x106:
2806
-    timer1Value = value;
2807
-    timerOnOffDelay|=2;
2808
-    cpuNextEvent = cpuTotalTicks;
2809
-    break;
2810
-  case 0x108:
2811
-    timer2Reload = value;
2812
-    break;
2813
-  case 0x10A:
2814
-    timer2Value = value;
2815
-    timerOnOffDelay|=4;
2816
-    cpuNextEvent = cpuTotalTicks;
2817
-    break;
2818
-  case 0x10C:
2819
-    timer3Reload = value;
2820
-    break;
2821
-  case 0x10E:
2822
-    timer3Value = value;
2823
-    timerOnOffDelay|=8;
2824
-    cpuNextEvent = cpuTotalTicks;
2825
-    break;
2826
-
2827
-
2828
-  /*case COMM_SIOCNT:
2829
-	  StartLink(value);
2830
-	  break;
2831
-
2832
-  case COMM_SIODATA8:
2833
-	  if (gba_link_enabled)
2834
-		  LinkSSend(value);
2835
-	  UPDATE_REG(COMM_SIODATA8, value);
2836
-	  break;*/
2837
-
2838
-  case 0x130:
2839
-	  P1 |= (value & 0x3FF);
2840
-	  UPDATE_REG(0x130, P1);
2841
-	  break;
2842
-
2843
-  case 0x132:
2844
-	  UPDATE_REG(0x132, value & 0xC3FF);
2845
-	  break;
2846
-
2847
-  /*case COMM_RCNT:
2848
-	  StartGPLink(value);
2849
-	  break;
2850
-
2851
-  case COMM_JOYCNT:
2852
-	  {
2853
-		  u16 cur = READ16LE(&ioMem[COMM_JOYCNT]);
2854
-
2855
-		  if (value & JOYCNT_RESET)			cur &= ~JOYCNT_RESET;
2856
-		  if (value & JOYCNT_RECV_COMPLETE)	cur &= ~JOYCNT_RECV_COMPLETE;
2857
-		  if (value & JOYCNT_SEND_COMPLETE)	cur &= ~JOYCNT_SEND_COMPLETE;
2858
-		  if (value & JOYCNT_INT_ENABLE)	cur |= JOYCNT_INT_ENABLE;
2859
-
2860
-		  UPDATE_REG(COMM_JOYCNT, cur);
2861
-	  }
2862
-	  break;
2863
-
2864
-  case COMM_JOY_RECV_L:
2865
-	  UPDATE_REG(COMM_JOY_RECV_L, value);
2866
-	  break;
2867
-  case COMM_JOY_RECV_H:
2868
-	  UPDATE_REG(COMM_JOY_RECV_H, value);
2869
-	  break;
2870
-
2871
-  case COMM_JOY_TRANS_L:
2872
-	  UPDATE_REG(COMM_JOY_TRANS_L, value);
2873
-	  UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND);
2874
-	  break;
2875
-  case COMM_JOY_TRANS_H:
2876
-	  UPDATE_REG(COMM_JOY_TRANS_H, value);
2877
-	  break;
2878
-
2879
-  case COMM_JOYSTAT:
2880
-	  UPDATE_REG(COMM_JOYSTAT, (READ16LE(&ioMem[COMM_JOYSTAT]) & 0xf) | (value & 0xf0));
2881
-	  break;*/
2882
-
2883
-  case 0x200:
2884
-    IE = value & 0x3FFF;
2885
-    UPDATE_REG(0x200, IE);
2886
-    if ((IME & 1) && (IF & IE) && armIrqEnable)
2887
-      cpuNextEvent = cpuTotalTicks;
2888
-    break;
2889
-  case 0x202:
2890
-    IF ^= (value & IF);
2891
-    UPDATE_REG(0x202, IF);
2892
-    break;
2893
-  case 0x204:
2894
-    {
2895
-      memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3];
2896
-
2897
-      if(!speedHack) {
2898
-        memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3];
2899
-        memoryWaitSeq[0x08] = memoryWaitSeq[0x09] =
2900
-          gamepakWaitState0[(value >> 4) & 1];
2901
-
2902
-        memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3];
2903
-        memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] =
2904
-          gamepakWaitState1[(value >> 7) & 1];
2905
-
2906
-        memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3];
2907
-        memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] =
2908
-          gamepakWaitState2[(value >> 10) & 1];
2909
-      } else {
2910
-        memoryWait[0x08] = memoryWait[0x09] = 3;
2911
-        memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = 1;
2912
-
2913
-        memoryWait[0x0a] = memoryWait[0x0b] = 3;
2914
-        memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = 1;
2915
-
2916
-        memoryWait[0x0c] = memoryWait[0x0d] = 3;
2917
-        memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = 1;
2918
-      }
2919
-
2920
-      for(int i = 8; i < 15; i++) {
2921
-        memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1;
2922
-        memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1;
2923
-      }
2924
-
2925
-      if((value & 0x4000) == 0x4000) {
2926
-        busPrefetchEnable = true;
2927
-        busPrefetch = false;
2928
-        busPrefetchCount = 0;
2929
-      } else {
2930
-        busPrefetchEnable = false;
2931
-        busPrefetch = false;
2932
-        busPrefetchCount = 0;
2933
-      }
2934
-      UPDATE_REG(0x204, value & 0x7FFF);
2935
-
2936
-    }
2937
-    break;
2938
-  case 0x208:
2939
-    IME = value & 1;
2940
-    UPDATE_REG(0x208, IME);
2941
-    if ((IME & 1) && (IF & IE) && armIrqEnable)
2942
-      cpuNextEvent = cpuTotalTicks;
2943
-    break;
2944
-  case 0x300:
2945
-    if(value != 0)
2946
-      value &= 0xFFFE;
2947
-    UPDATE_REG(0x300, value);
2948
-    break;
2949
-  default:
2950
-    UPDATE_REG(address&0x3FE, value);
2951
-    break;
2952
-  }
976
+	switch (address)
977
+	{
978
+		case 0x00:
979
+		{
980
+			if ((value & 7) > 5)
981
+				// display modes above 0-5 are prohibited
982
+				DISPCNT = value & 7;
983
+			bool change = !!((DISPCNT ^ value) & 0x80);
984
+			uint16_t changeBGon = (~DISPCNT & value) & 0x0F00; // these layers are being activated
985
+
986
+			DISPCNT = value & 0xFFF7; // bit 3 can only be accessed by the BIOS to enable GBC mode
987
+			UPDATE_REG(0x00, DISPCNT);
988
+
989
+			if (changeBGon)
990
+			{
991
+				layerEnableDelay = 4;
992
+				layerEnable = layerSettings & value & ~changeBGon;
993
+			}
994
+			else
995
+			{
996
+				layerEnable = layerSettings & value;
997
+				//CPUUpdateTicks();
998
+			}
999
+
1000
+			if (change && !(value & 0x80))
1001
+			{
1002
+				if (!(DISPSTAT & 1))
1003
+				{
1004
+					lcdTicks = 1008;
1005
+					DISPSTAT &= 0xFFFC;
1006
+					UPDATE_REG(0x04, DISPSTAT);
1007
+					CPUCompareVCOUNT();
1008
+				}
1009
+			}
1010
+			break;
1011
+		}
1012
+		case 0x04:
1013
+			DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7);
1014
+			UPDATE_REG(0x04, DISPSTAT);
1015
+			break;
1016
+		case 0x06:
1017
+			// not writable
1018
+			break;
1019
+		case 0x08:
1020
+			BG0CNT = value & 0xDFCF;
1021
+			UPDATE_REG(0x08, BG0CNT);
1022
+			break;
1023
+		case 0x0A:
1024
+			BG1CNT = value & 0xDFCF;
1025
+			UPDATE_REG(0x0A, BG1CNT);
1026
+			break;
1027
+		case 0x0C:
1028
+			BG2CNT = value & 0xFFCF;
1029
+			UPDATE_REG(0x0C, BG2CNT);
1030
+			break;
1031
+		case 0x0E:
1032
+			BG3CNT = value & 0xFFCF;
1033
+			UPDATE_REG(0x0E, BG3CNT);
1034
+			break;
1035
+		case 0x10:
1036
+			BG0HOFS = value & 511;
1037
+			UPDATE_REG(0x10, BG0HOFS);
1038
+			break;
1039
+		case 0x12:
1040
+			BG0VOFS = value & 511;
1041
+			UPDATE_REG(0x12, BG0VOFS);
1042
+			break;
1043
+		case 0x14:
1044
+			BG1HOFS = value & 511;
1045
+			UPDATE_REG(0x14, BG1HOFS);
1046
+			break;
1047
+		case 0x16:
1048
+			BG1VOFS = value & 511;
1049
+			UPDATE_REG(0x16, BG1VOFS);
1050
+			break;
1051
+		case 0x18:
1052
+			BG2HOFS = value & 511;
1053
+			UPDATE_REG(0x18, BG2HOFS);
1054
+			break;
1055
+		case 0x1A:
1056
+			BG2VOFS = value & 511;
1057
+			UPDATE_REG(0x1A, BG2VOFS);
1058
+			break;
1059
+		case 0x1C:
1060
+			BG3HOFS = value & 511;
1061
+			UPDATE_REG(0x1C, BG3HOFS);
1062
+			break;
1063
+		case 0x1E:
1064
+			BG3VOFS = value & 511;
1065
+			UPDATE_REG(0x1E, BG3VOFS);
1066
+			break;
1067
+		case 0x20:
1068
+			BG2PA = value;
1069
+			UPDATE_REG(0x20, BG2PA);
1070
+			break;
1071
+		case 0x22:
1072
+			BG2PB = value;
1073
+			UPDATE_REG(0x22, BG2PB);
1074
+			break;
1075
+		case 0x24:
1076
+			BG2PC = value;
1077
+			UPDATE_REG(0x24, BG2PC);
1078
+			break;
1079
+		case 0x26:
1080
+			BG2PD = value;
1081
+			UPDATE_REG(0x26, BG2PD);
1082
+			break;
1083
+		case 0x28:
1084
+			BG2X_L = value;
1085
+			UPDATE_REG(0x28, BG2X_L);
1086
+			break;
1087
+		case 0x2A:
1088
+			BG2X_H = (value & 0xFFF);
1089
+			UPDATE_REG(0x2A, BG2X_H);
1090
+			break;
1091
+		case 0x2C:
1092
+			BG2Y_L = value;
1093
+			UPDATE_REG(0x2C, BG2Y_L);
1094
+			break;
1095
+		case 0x2E:
1096
+			BG2Y_H = value & 0xFFF;
1097
+			UPDATE_REG(0x2E, BG2Y_H);
1098
+			break;
1099
+		case 0x30:
1100
+			BG3PA = value;
1101
+			UPDATE_REG(0x30, BG3PA);
1102
+			break;
1103
+		case 0x32:
1104
+			BG3PB = value;
1105
+			UPDATE_REG(0x32, BG3PB);
1106
+			break;
1107
+		case 0x34:
1108
+			BG3PC = value;
1109
+			UPDATE_REG(0x34, BG3PC);
1110
+			break;
1111
+		case 0x36:
1112
+			BG3PD = value;
1113
+			UPDATE_REG(0x36, BG3PD);
1114
+			break;
1115
+		case 0x38:
1116
+			BG3X_L = value;
1117
+			UPDATE_REG(0x38, BG3X_L);
1118
+			break;
1119
+		case 0x3A:
1120
+			BG3X_H = value & 0xFFF;
1121
+			UPDATE_REG(0x3A, BG3X_H);
1122
+			break;
1123
+		case 0x3C:
1124
+			BG3Y_L = value;
1125
+			UPDATE_REG(0x3C, BG3Y_L);
1126
+			break;
1127
+		case 0x3E:
1128
+			BG3Y_H = value & 0xFFF;
1129
+			UPDATE_REG(0x3E, BG3Y_H);
1130
+			break;
1131
+		case 0x40:
1132
+			WIN0H = value;
1133
+			UPDATE_REG(0x40, WIN0H);
1134
+			break;
1135
+		case 0x42:
1136
+			WIN1H = value;
1137
+			UPDATE_REG(0x42, WIN1H);
1138
+			break;
1139
+		case 0x44:
1140
+			WIN0V = value;
1141
+			UPDATE_REG(0x44, WIN0V);
1142
+			break;
1143
+		case 0x46:
1144
+			WIN1V = value;
1145
+			UPDATE_REG(0x46, WIN1V);
1146
+			break;
1147
+		case 0x48:
1148
+			WININ = value & 0x3F3F;
1149
+			UPDATE_REG(0x48, WININ);
1150
+			break;
1151
+		case 0x4A:
1152
+			WINOUT = value & 0x3F3F;
1153
+			UPDATE_REG(0x4A, WINOUT);
1154
+			break;
1155
+		case 0x4C:
1156
+			MOSAIC = value;
1157
+			UPDATE_REG(0x4C, MOSAIC);
1158
+			break;
1159
+		case 0x50:
1160
+			BLDMOD = value & 0x3FFF;
1161
+			UPDATE_REG(0x50, BLDMOD);
1162
+			break;
1163
+		case 0x52:
1164
+			COLEV = value & 0x1F1F;
1165
+			UPDATE_REG(0x52, COLEV);
1166
+			break;
1167
+		case 0x54:
1168
+			COLY = value & 0x1F;
1169
+			UPDATE_REG(0x54, COLY);
1170
+			break;
1171
+		case 0x60:
1172
+		case 0x62:
1173
+		case 0x64:
1174
+		case 0x68:
1175
+		case 0x6c:
1176
+		case 0x70:
1177
+		case 0x72:
1178
+		case 0x74:
1179
+		case 0x78:
1180
+		case 0x7c:
1181
+		case 0x80:
1182
+		case 0x84:
1183
+			soundEvent(address & 0xFF, static_cast<uint8_t>(value & 0xFF));
1184
+			soundEvent((address & 0xFF) + 1, static_cast<uint8_t>(value >> 8));
1185
+			break;
1186
+		case 0x82:
1187
+		case 0x88:
1188
+		case 0xa0:
1189
+		case 0xa2:
1190
+		case 0xa4:
1191
+		case 0xa6:
1192
+		case 0x90:
1193
+		case 0x92:
1194
+		case 0x94:
1195
+		case 0x96:
1196
+		case 0x98:
1197
+		case 0x9a:
1198
+		case 0x9c:
1199
+		case 0x9e:
1200
+			soundEvent(address & 0xFF, value);
1201
+			break;
1202
+		case 0xB0:
1203
+			DM0SAD_L = value;
1204
+			UPDATE_REG(0xB0, DM0SAD_L);
1205
+			break;
1206
+		case 0xB2:
1207
+			DM0SAD_H = value & 0x07FF;
1208
+			UPDATE_REG(0xB2, DM0SAD_H);
1209
+			break;
1210
+		case 0xB4:
1211
+			DM0DAD_L = value;
1212
+			UPDATE_REG(0xB4, DM0DAD_L);
1213
+			break;
1214
+		case 0xB6:
1215
+			DM0DAD_H = value & 0x07FF;
1216
+			UPDATE_REG(0xB6, DM0DAD_H);
1217
+			break;
1218
+		case 0xB8:
1219
+			DM0CNT_L = value & 0x3FFF;
1220
+			UPDATE_REG(0xB8, 0);
1221
+			break;
1222
+		case 0xBA:
1223
+		{
1224
+			bool start = !!((DM0CNT_H ^ value) & 0x8000);
1225
+			value &= 0xF7E0;
1226
+
1227
+			DM0CNT_H = value;
1228
+			UPDATE_REG(0xBA, DM0CNT_H);
1229
+
1230
+			if (start && (value & 0x8000))
1231
+			{
1232
+				dma0Source = DM0SAD_L | (DM0SAD_H << 16);
1233
+				dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
1234
+				CPUCheckDMA(0, 1);
1235
+			}
1236
+			break;
1237
+		}
1238
+		case 0xBC:
1239
+			DM1SAD_L = value;
1240
+			UPDATE_REG(0xBC, DM1SAD_L);
1241
+			break;
1242
+		case 0xBE:
1243
+			DM1SAD_H = value & 0x0FFF;
1244
+			UPDATE_REG(0xBE, DM1SAD_H);
1245
+			break;
1246
+		case 0xC0:
1247
+			DM1DAD_L = value;
1248
+			UPDATE_REG(0xC0, DM1DAD_L);
1249
+			break;
1250
+		case 0xC2:
1251
+			DM1DAD_H = value & 0x07FF;
1252
+			UPDATE_REG(0xC2, DM1DAD_H);
1253
+			break;
1254
+		case 0xC4:
1255
+			DM1CNT_L = value & 0x3FFF;
1256
+			UPDATE_REG(0xC4, 0);
1257
+			break;
1258
+		case 0xC6:
1259
+		{
1260
+			bool start = !!((DM1CNT_H ^ value) & 0x8000);
1261
+			value &= 0xF7E0;
1262
+
1263
+			DM1CNT_H = value;
1264
+			UPDATE_REG(0xC6, DM1CNT_H);
1265
+
1266
+			if (start && (value & 0x8000))
1267
+			{
1268
+				dma1Source = DM1SAD_L | (DM1SAD_H << 16);
1269
+				dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
1270
+				CPUCheckDMA(0, 2);
1271
+			}
1272
+			break;
1273
+		}
1274
+		case 0xC8:
1275
+			DM2SAD_L = value;
1276
+			UPDATE_REG(0xC8, DM2SAD_L);
1277
+			break;
1278
+		case 0xCA:
1279
+			DM2SAD_H = value & 0x0FFF;
1280
+			UPDATE_REG(0xCA, DM2SAD_H);
1281
+			break;
1282
+		case 0xCC:
1283
+			DM2DAD_L = value;
1284
+			UPDATE_REG(0xCC, DM2DAD_L);
1285
+			break;
1286
+		case 0xCE:
1287
+			DM2DAD_H = value & 0x07FF;
1288
+			UPDATE_REG(0xCE, DM2DAD_H);
1289
+			break;
1290
+		case 0xD0:
1291
+			DM2CNT_L = value & 0x3FFF;
1292
+			UPDATE_REG(0xD0, 0);
1293
+			break;
1294
+		case 0xD2:
1295
+		{
1296
+			bool start = !!((DM2CNT_H ^ value) & 0x8000);
1297
+			value &= 0xF7E0;
1298
+
1299
+			DM2CNT_H = value;
1300
+			UPDATE_REG(0xD2, DM2CNT_H);
1301
+
1302
+			if (start && (value & 0x8000))
1303
+			{
1304
+				dma2Source = DM2SAD_L | (DM2SAD_H << 16);
1305
+				dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
1306
+				CPUCheckDMA(0, 4);
1307
+			}
1308
+			break;
1309
+		}
1310
+		case 0xD4:
1311
+			DM3SAD_L = value;
1312
+			UPDATE_REG(0xD4, DM3SAD_L);
1313
+			break;
1314
+		case 0xD6:
1315
+			DM3SAD_H = value & 0x0FFF;
1316
+			UPDATE_REG(0xD6, DM3SAD_H);
1317
+			break;
1318
+		case 0xD8:
1319
+			DM3DAD_L = value;
1320
+			UPDATE_REG(0xD8, DM3DAD_L);
1321
+			break;
1322
+		case 0xDA:
1323
+			DM3DAD_H = value & 0x0FFF;
1324
+			UPDATE_REG(0xDA, DM3DAD_H);
1325
+			break;
1326
+		case 0xDC:
1327
+			DM3CNT_L = value;
1328
+			UPDATE_REG(0xDC, 0);
1329
+			break;
1330
+		case 0xDE:
1331
+		{
1332
+			bool start = !!((DM3CNT_H ^ value) & 0x8000);
1333
+			value &= 0xFFE0;
1334
+
1335
+			DM3CNT_H = value;
1336
+			UPDATE_REG(0xDE, DM3CNT_H);
1337
+
1338
+			if (start && (value & 0x8000))
1339
+			{
1340
+				dma3Source = DM3SAD_L | (DM3SAD_H << 16);
1341
+				dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
1342
+				CPUCheckDMA(0, 8);
1343
+			}
1344
+			break;
1345
+		}
1346
+		case 0x100:
1347
+			timer0Reload = value;
1348
+			break;
1349
+		case 0x102:
1350
+			timer0Value = value;
1351
+			timerOnOffDelay |= 1;
1352
+			cpuNextEvent = cpuTotalTicks;
1353
+			break;
1354
+		case 0x104:
1355
+			timer1Reload = value;
1356
+			break;
1357
+		case 0x106:
1358
+			timer1Value = value;
1359
+			timerOnOffDelay |= 2;
1360
+			cpuNextEvent = cpuTotalTicks;
1361
+			break;
1362
+		case 0x108:
1363
+			timer2Reload = value;
1364
+			break;
1365
+		case 0x10A:
1366
+			timer2Value = value;
1367
+			timerOnOffDelay |= 4;
1368
+			cpuNextEvent = cpuTotalTicks;
1369
+			break;
1370
+		case 0x10C:
1371
+			timer3Reload = value;
1372
+			break;
1373
+		case 0x10E:
1374
+			timer3Value = value;
1375
+			timerOnOffDelay |= 8;
1376
+			cpuNextEvent = cpuTotalTicks;
1377
+			break;
1378
+
1379
+		case 0x130:
1380
+			P1 |= value & 0x3FF;
1381
+			UPDATE_REG(0x130, P1);
1382
+			break;
1383
+
1384
+		case 0x132:
1385
+			UPDATE_REG(0x132, value & 0xC3FF);
1386
+			break;
1387
+
1388
+		case 0x200:
1389
+			IE = value & 0x3FFF;
1390
+			UPDATE_REG(0x200, IE);
1391
+			if ((IME & 1) && (IF & IE) && armIrqEnable)
1392
+				cpuNextEvent = cpuTotalTicks;
1393
+			break;
1394
+		case 0x202:
1395
+			IF ^= value & IF;
1396
+			UPDATE_REG(0x202, IF);
1397
+			break;
1398
+		case 0x204:
1399
+			memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3];
1400
+
1401
+			memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3];
1402
+			memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = gamepakWaitState0[(value >> 4) & 1];
1403
+
1404
+			memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3];
1405
+			memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = gamepakWaitState1[(value >> 7) & 1];
1406
+
1407
+			memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3];
1408
+			memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = gamepakWaitState2[(value >> 10) & 1];
1409
+
1410
+			for (int i = 8; i < 15; ++i)
1411
+			{
1412
+				memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1;
1413
+				memoryWaitSeq32[i] = memoryWaitSeq[i] * 2 + 1;
1414
+			}
1415
+
1416
+			busPrefetchEnable = (value & 0x4000) == 0x4000;
1417
+			busPrefetch = false;
1418
+			busPrefetchCount = 0;
1419
+			UPDATE_REG(0x204, value & 0x7FFF);
1420
+
1421
+			break;
1422
+		case 0x208:
1423
+			IME = value & 1;
1424
+			UPDATE_REG(0x208, IME);
1425
+			if ((IME & 1) && (IF & IE) && armIrqEnable)
1426
+				cpuNextEvent = cpuTotalTicks;
1427
+			break;
1428
+		case 0x300:
1429
+			if (value)
1430
+				value &= 0xFFFE;
1431
+			UPDATE_REG(0x300, value);
1432
+			break;
1433
+		default:
1434
+			UPDATE_REG(address & 0x3FE, value);
1435
+	}
2953 1436
 }
2954 1437
 
2955
-void applyTimer ()
1438
+void applyTimer()
2956 1439
 {
2957
-  if (timerOnOffDelay & 1)
2958
-  {
2959
-    timer0ClockReload = TIMER_TICKS[timer0Value & 3];
2960
-    if(!timer0On && (timer0Value & 0x80)) {
2961
-      // reload the counter
2962
-      TM0D = timer0Reload;
2963
-      timer0Ticks = (0x10000 - TM0D) << timer0ClockReload;
2964
-      UPDATE_REG(0x100, TM0D);
2965
-    }
2966
-    timer0On = timer0Value & 0x80 ? true : false;
2967
-    TM0CNT = timer0Value & 0xC7;
2968
-    interp_rate();
2969
-    UPDATE_REG(0x102, TM0CNT);
2970
-    //    CPUUpdateTicks();
2971
-  }
2972
-  if (timerOnOffDelay & 2)
2973
-  {
2974
-    timer1ClockReload = TIMER_TICKS[timer1Value & 3];
2975
-    if(!timer1On && (timer1Value & 0x80)) {
2976
-      // reload the counter
2977
-      TM1D = timer1Reload;
2978
-      timer1Ticks = (0x10000 - TM1D) << timer1ClockReload;
2979
-      UPDATE_REG(0x104, TM1D);
2980
-    }
2981
-    timer1On = timer1Value & 0x80 ? true : false;
2982
-    TM1CNT = timer1Value & 0xC7;
2983
-    interp_rate();
2984
-    UPDATE_REG(0x106, TM1CNT);
2985
-  }
2986
-  if (timerOnOffDelay & 4)
2987
-  {
2988
-    timer2ClockReload = TIMER_TICKS[timer2Value & 3];
2989
-    if(!timer2On && (timer2Value & 0x80)) {
2990
-      // reload the counter
2991
-      TM2D = timer2Reload;
2992
-      timer2Ticks = (0x10000 - TM2D) << timer2ClockReload;
2993
-      UPDATE_REG(0x108, TM2D);
2994
-    }
2995
-    timer2On = timer2Value & 0x80 ? true : false;
2996
-    TM2CNT = timer2Value & 0xC7;
2997
-    UPDATE_REG(0x10A, TM2CNT);
2998
-  }
2999
-  if (timerOnOffDelay & 8)
3000
-  {
3001
-    timer3ClockReload = TIMER_TICKS[timer3Value & 3];
3002
-    if(!timer3On && (timer3Value & 0x80)) {
3003
-      // reload the counter
3004
-      TM3D = timer3Reload;
3005
-      timer3Ticks = (0x10000 - TM3D) << timer3ClockReload;
3006
-      UPDATE_REG(0x10C, TM3D);
3007
-    }
3008
-    timer3On = timer3Value & 0x80 ? true : false;
3009
-    TM3CNT = timer3Value & 0xC7;
3010
-    UPDATE_REG(0x10E, TM3CNT);
3011
-  }
3012
-  cpuNextEvent = CPUUpdateTicks();
3013
-  timerOnOffDelay = 0;
1440
+	if (timerOnOffDelay & 1)
1441
+	{
1442
+		timer0ClockReload = TIMER_TICKS[timer0Value & 3];
1443
+		if (!timer0On && (timer0Value & 0x80))
1444
+		{
1445
+			// reload the counter
1446
+			TM0D = timer0Reload;
1447
+			timer0Ticks = (0x10000 - TM0D) << timer0ClockReload;
1448
+			UPDATE_REG(0x100, TM0D);
1449
+		}
1450
+		timer0On = !!(timer0Value & 0x80);
1451
+		TM0CNT = timer0Value & 0xC7;
1452
+		UPDATE_REG(0x102, TM0CNT);
1453
+		//CPUUpdateTicks();
1454
+	}
1455
+	if (timerOnOffDelay & 2)
1456
+	{
1457
+		timer1ClockReload = TIMER_TICKS[timer1Value & 3];
1458
+		if (!timer1On && (timer1Value & 0x80))
1459
+		{
1460
+			// reload the counter
1461
+			TM1D = timer1Reload;
1462
+			timer1Ticks = (0x10000 - TM1D) << timer1ClockReload;
1463
+			UPDATE_REG(0x104, TM1D);
1464
+		}
1465
+		timer1On = !!(timer1Value & 0x80);
1466
+		TM1CNT = timer1Value & 0xC7;
1467
+		UPDATE_REG(0x106, TM1CNT);
1468
+	}
1469
+	if (timerOnOffDelay & 4)
1470
+	{
1471
+		timer2ClockReload = TIMER_TICKS[timer2Value & 3];
1472
+		if (!timer2On && (timer2Value & 0x80))
1473
+		{
1474
+			// reload the counter
1475
+			TM2D = timer2Reload;
1476
+			timer2Ticks = (0x10000 - TM2D) << timer2ClockReload;
1477
+			UPDATE_REG(0x108, TM2D);
1478
+		}
1479
+		timer2On = !(timer2Value & 0x80);
1480
+		TM2CNT = timer2Value & 0xC7;
1481
+		UPDATE_REG(0x10A, TM2CNT);
1482
+	}
1483
+	if (timerOnOffDelay & 8)
1484
+	{
1485
+		timer3ClockReload = TIMER_TICKS[timer3Value & 3];
1486
+		if (!timer3On && (timer3Value & 0x80))
1487
+		{
1488
+			// reload the counter
1489
+			TM3D = timer3Reload;
1490
+			timer3Ticks = (0x10000 - TM3D) << timer3ClockReload;
1491
+			UPDATE_REG(0x10C, TM3D);
1492
+		}
1493
+		timer3On = !!(timer3Value & 0x80);
1494
+		TM3CNT = timer3Value & 0xC7;
1495
+		UPDATE_REG(0x10E, TM3CNT);
1496
+	}
1497
+	cpuNextEvent = CPUUpdateTicks();
1498
+	timerOnOffDelay = 0;
3014 1499
 }
3015 1500
 
3016 1501
 uint8_t cpuBitsSet[256];
3017 1502
 uint8_t cpuLowestBitSet[256];
3018 1503
 
3019
-void CPUInit(const char *biosFileName, bool useBiosFile)
1504
+void CPUInit()
3020 1505
 {
3021 1506
 #ifdef WORDS_BIGENDIAN
3022
-  if(!cpuBiosSwapped) {
3023
-    for(unsigned int i = 0; i < sizeof(myROM)/4; i++) {
3024
-      WRITE32LE(&myROM[i], myROM[i]);
3025
-    }
3026
-    cpuBiosSwapped = true;
3027
-  }
1507
+	if (!cpuBiosSwapped)
1508
+	{
1509
+		for (unsigned i = 0; i < sizeof(myROM) / 4; ++i)
1510
+			WRITE32LE(&myROM[i], myROM[i]);
1511
+		cpuBiosSwapped = true;
1512
+	}
3028 1513
 #endif
3029
-  gbaSaveType = 0;
3030
-  //eepromInUse = 0;
3031
-  saveType = 0;
3032
-  useBios = false;
3033
-
3034
-  /*if(useBiosFile) {
3035
-    int size = 0x4000;
3036
-    if(utilLoad(biosFileName,
3037
-                CPUIsGBABios,
3038
-                bios,
3039
-                size)) {
3040
-      if(size == 0x4000)
3041
-        useBios = true;
3042
-      else
3043
-        systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BIOS file size"));
3044
-    }
3045
-  }*/
3046
-
3047
-  if(!useBios) {
3048
-    memcpy(bios, myROM, sizeof(myROM));
3049
-  }
3050
-
3051
-  int i = 0;
3052
-
3053
-  biosProtected[0] = 0x00;
3054
-  biosProtected[1] = 0xf0;
3055
-  biosProtected[2] = 0x29;
3056
-  biosProtected[3] = 0xe1;
3057
-
3058
-  for(i = 0; i < 256; i++) {
3059
-    int count = 0;
3060
-    int j;
3061
-    for(j = 0; j < 8; j++)
3062
-      if(i & (1 << j))
3063
-        count++;
3064
-    cpuBitsSet[i] = count;
3065
-
3066
-    for(j = 0; j < 8; j++)
3067
-      if(i & (1 << j))
3068
-        break;
3069
-    cpuLowestBitSet[i] = j;
3070
-  }
3071
-
3072
-  for(i = 0; i < 0x400; i++)
3073
-    ioReadable[i] = true;
3074
-  for(i = 0x10; i < 0x48; i++)
3075
-    ioReadable[i] = false;
3076
-  for(i = 0x4c; i < 0x50; i++)
3077
-    ioReadable[i] = false;
3078
-  for(i = 0x54; i < 0x60; i++)
3079
-    ioReadable[i] = false;
3080
-  for(i = 0x8c; i < 0x90; i++)
3081
-    ioReadable[i] = false;
3082
-  for(i = 0xa0; i < 0xb8; i++)
3083
-    ioReadable[i] = false;
3084
-  for(i = 0xbc; i < 0xc4; i++)
3085
-    ioReadable[i] = false;
3086
-  for(i = 0xc8; i < 0xd0; i++)
3087
-    ioReadable[i] = false;
3088
-  for(i = 0xd4; i < 0xdc; i++)
3089
-    ioReadable[i] = false;
3090
-  for(i = 0xe0; i < 0x100; i++)
3091
-    ioReadable[i] = false;
3092
-  for(i = 0x110; i < 0x120; i++)
3093
-    ioReadable[i] = false;
3094
-  for(i = 0x12c; i < 0x130; i++)
3095
-    ioReadable[i] = false;
3096
-  for(i = 0x138; i < 0x140; i++)
3097
-    ioReadable[i] = false;
3098
-  for(i = 0x144; i < 0x150; i++)
3099
-    ioReadable[i] = false;
3100
-  for(i = 0x15c; i < 0x200; i++)
3101
-    ioReadable[i] = false;
3102
-  for(i = 0x20c; i < 0x300; i++)
3103
-    ioReadable[i] = false;
3104
-  for(i = 0x304; i < 0x400; i++)
3105
-    ioReadable[i] = false;
3106
-
3107
-  if(romSize < 0x1fe2000) {
3108
-    *((uint16_t *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA
3109
-    *((uint16_t *)&rom[0x1fe209e]) = 0x4770; // BX LR
3110
-  } else {
3111
-    //agbPrintEnable(false);
3112
-  }
1514
+	memcpy(&bios[0], myROM, sizeof(myROM));
1515
+
1516
+	biosProtected[0] = 0x00;
1517
+	biosProtected[1] = 0xf0;
1518
+	biosProtected[2] = 0x29;
1519
+	biosProtected[3] = 0xe1;
1520
+
1521
+	for (int i = 0; i < 256; ++i)
1522
+	{
1523
+		int count = 0;
1524
+		int j;
1525
+		for (j = 0; j < 8; ++j)
1526
+			if (i & (1 << j))
1527
+				++count;
1528
+		cpuBitsSet[i] = count;
1529
+
1530
+		for (j = 0; j < 8; ++j)
1531
+			if (i & (1 << j))
1532
+				break;
1533
+		cpuLowestBitSet[i] = j;
1534
+	}
1535
+
1536
+	std::fill(&ioReadable[0], &ioReadable[0x304], true);
1537
+	std::fill(&ioReadable[0x10], &ioReadable[0x48], false);
1538
+	std::fill(&ioReadable[0x4c], &ioReadable[0x50], false);
1539
+	std::fill(&ioReadable[0x54], &ioReadable[0x60], false);
1540
+	std::fill(&ioReadable[0x8c], &ioReadable[0x90], false);
1541
+	std::fill(&ioReadable[0xa0], &ioReadable[0xb8], false);
1542
+	std::fill(&ioReadable[0xbc], &ioReadable[0xc4], false);
1543
+	std::fill(&ioReadable[0xc8], &ioReadable[0xd0], false);
1544
+	std::fill(&ioReadable[0xd4], &ioReadable[0xdc], false);
1545
+	std::fill(&ioReadable[0xe0], &ioReadable[0x100], false);
1546
+	std::fill(&ioReadable[0x110], &ioReadable[0x120], false);
1547
+	std::fill(&ioReadable[0x12c], &ioReadable[0x130], false);
1548
+	std::fill(&ioReadable[0x138], &ioReadable[0x140], false);
1549
+	std::fill(&ioReadable[0x144], &ioReadable[0x150], false);
1550
+	std::fill(&ioReadable[0x15c], &ioReadable[0x200], false);
1551
+	std::fill(&ioReadable[0x20c], &ioReadable[0x300], false);
1552
+	std::fill(&ioReadable[0x304], &ioReadable[0x400], false);
1553
+
1554
+	if (romSize < 0x1fe2000)
1555
+	{
1556
+		*reinterpret_cast<uint16_t *>(&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA
1557
+		*reinterpret_cast<uint16_t *>(&rom[0x1fe209e]) = 0x4770; // BX LR
1558
+	}
3113 1559
 }
3114 1560
 
3115 1561
 void CPUReset()
3116 1562
 {
3117
-  /*if(gbaSaveType == 0) {
3118
-    if(eepromInUse)
3119
-      gbaSaveType = 3;
3120
-    else
3121
-      switch(saveType) {
3122
-      case 1:
3123
-        gbaSaveType = 1;
3124
-        break;
3125
-      case 2:
3126
-        gbaSaveType = 2;
3127
-        break;
3128
-      }
3129
-  }
3130
-  rtcReset();*/
3131
-  // clean registers
3132
-  memset(&reg[0], 0, sizeof(reg));
3133
-  // clean OAM
3134
-  memset(oam, 0, 0x400);
3135
-  // clean palette
3136
-  memset(paletteRAM, 0, 0x400);
3137
-  // clean picture
3138
-  memset(pix, 0, 4*160*240);
3139
-  // clean vram
3140
-  memset(vram, 0, 0x20000);
3141
-  // clean io memory
3142
-  memset(ioMem, 0, 0x400);
3143
-
3144
-  DISPCNT  = 0x0080;
3145
-  DISPSTAT = 0x0000;
3146
-  VCOUNT   = (useBios && !skipBios) ? 0 :0x007E;
3147
-  BG0CNT   = 0x0000;
3148
-  BG1CNT   = 0x0000;
3149
-  BG2CNT   = 0x0000;
3150
-  BG3CNT   = 0x0000;
3151
-  BG0HOFS  = 0x0000;
3152
-  BG0VOFS  = 0x0000;
3153
-  BG1HOFS  = 0x0000;
3154
-  BG1VOFS  = 0x0000;
3155
-  BG2HOFS  = 0x0000;
3156
-  BG2VOFS  = 0x0000;
3157
-  BG3HOFS  = 0x0000;
3158
-  BG3VOFS  = 0x0000;
3159
-  BG2PA    = 0x0100;
3160
-  BG2PB    = 0x0000;
3161
-  BG2PC    = 0x0000;
3162
-  BG2PD    = 0x0100;
3163
-  BG2X_L   = 0x0000;
3164
-  BG2X_H   = 0x0000;
3165
-  BG2Y_L   = 0x0000;
3166
-  BG2Y_H   = 0x0000;
3167
-  BG3PA    = 0x0100;
3168
-  BG3PB    = 0x0000;
3169
-  BG3PC    = 0x0000;
3170
-  BG3PD    = 0x0100;
3171
-  BG3X_L   = 0x0000;
3172
-  BG3X_H   = 0x0000;
3173
-  BG3Y_L   = 0x0000;
3174
-  BG3Y_H   = 0x0000;
3175
-  WIN0H    = 0x0000;
3176
-  WIN1H    = 0x0000;
3177
-  WIN0V    = 0x0000;
3178
-  WIN1V    = 0x0000;
3179
-  WININ    = 0x0000;
3180
-  WINOUT   = 0x0000;
3181
-  MOSAIC   = 0x0000;
3182
-  BLDMOD   = 0x0000;
3183
-  COLEV    = 0x0000;
3184
-  COLY     = 0x0000;
3185
-  DM0SAD_L = 0x0000;
3186
-  DM0SAD_H = 0x0000;
3187
-  DM0DAD_L = 0x0000;
3188
-  DM0DAD_H = 0x0000;
3189
-  DM0CNT_L = 0x0000;
3190
-  DM0CNT_H = 0x0000;
3191
-  DM1SAD_L = 0x0000;
3192
-  DM1SAD_H = 0x0000;
3193
-  DM1DAD_L = 0x0000;
3194
-  DM1DAD_H = 0x0000;
3195
-  DM1CNT_L = 0x0000;
3196
-  DM1CNT_H = 0x0000;
3197
-  DM2SAD_L = 0x0000;
3198
-  DM2SAD_H = 0x0000;
3199
-  DM2DAD_L = 0x0000;
3200
-  DM2DAD_H = 0x0000;
3201
-  DM2CNT_L = 0x0000;
3202
-  DM2CNT_H = 0x0000;
3203
-  DM3SAD_L = 0x0000;
3204
-  DM3SAD_H = 0x0000;
3205
-  DM3DAD_L = 0x0000;
3206
-  DM3DAD_H = 0x0000;
3207
-  DM3CNT_L = 0x0000;
3208
-  DM3CNT_H = 0x0000;
3209
-  TM0D     = 0x0000;
3210
-  TM0CNT   = 0x0000;
3211
-  TM1D     = 0x0000;
3212
-  TM1CNT   = 0x0000;
3213
-  TM2D     = 0x0000;
3214
-  TM2CNT   = 0x0000;
3215
-  TM3D     = 0x0000;
3216
-  TM3CNT   = 0x0000;
3217
-  P1       = 0x03FF;
3218
-  IE       = 0x0000;
3219
-  IF       = 0x0000;
3220
-  IME      = 0x0000;
3221
-
3222
-  armMode = 0x1F;
3223
-
3224
-  if(cpuIsMultiBoot) {
3225
-    reg[13].I = 0x03007F00;
3226
-    reg[15].I = 0x02000000;
3227
-    reg[16].I = 0x00000000;
3228
-    reg[R13_IRQ].I = 0x03007FA0;
3229
-    reg[R13_SVC].I = 0x03007FE0;
3230
-    armIrqEnable = true;
3231
-  } else {
3232
-    if(useBios && !skipBios) {
3233
-      reg[15].I = 0x00000000;
3234
-      armMode = 0x13;
3235
-      armIrqEnable = false;
3236
-    } else {
3237
-      reg[13].I = 0x03007F00;
3238
-      reg[15].I = 0x08000000;
3239
-      reg[16].I = 0x00000000;
3240
-      reg[R13_IRQ].I = 0x03007FA0;
3241
-      reg[R13_SVC].I = 0x03007FE0;
3242
-      armIrqEnable = true;
3243
-    }
3244
-  }
3245
-  armState = true;
3246
-  C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false;
3247
-  UPDATE_REG(0x00, DISPCNT);
3248
-  UPDATE_REG(0x06, VCOUNT);
3249
-  UPDATE_REG(0x20, BG2PA);
3250
-  UPDATE_REG(0x26, BG2PD);
3251
-  UPDATE_REG(0x30, BG3PA);
3252
-  UPDATE_REG(0x36, BG3PD);
3253
-  UPDATE_REG(0x130, P1);
3254
-  UPDATE_REG(0x88, 0x200);
3255
-
3256
-  // disable FIQ
3257
-  reg[16].I |= 0x40;
3258
-
3259
-  CPUUpdateCPSR();
3260
-
3261
-  armNextPC = reg[15].I;
3262
-  reg[15].I += 4;
3263
-
3264
-  // reset internal state
3265
-  holdState = false;
3266
-  holdType = 0;
3267
-
3268
-  biosProtected[0] = 0x00;
3269
-  biosProtected[1] = 0xf0;
3270
-  biosProtected[2] = 0x29;
3271
-  biosProtected[3] = 0xe1;
3272
-
3273
-  lcdTicks = (useBios && !skipBios) ? 1008 : 208;
3274
-  timer0On = false;
3275
-  timer0Ticks = 0;
3276
-  timer0Reload = 0;
3277
-  timer0ClockReload  = 0;
3278
-  timer1On = false;
3279
-  timer1Ticks = 0;
3280
-  timer1Reload = 0;
3281
-  timer1ClockReload  = 0;
3282
-  timer2On = false;
3283
-  timer2Ticks = 0;
3284
-  timer2Reload = 0;
3285
-  timer2ClockReload  = 0;
3286
-  timer3On = false;
3287
-  timer3Ticks = 0;
3288
-  timer3Reload = 0;
3289
-  timer3ClockReload  = 0;
3290
-  dma0Source = 0;
3291
-  dma0Dest = 0;
3292
-  dma1Source = 0;
3293
-  dma1Dest = 0;
3294
-  dma2Source = 0;
3295
-  dma2Dest = 0;
3296
-  dma3Source = 0;
3297
-  dma3Dest = 0;
3298
-  //cpuSaveGameFunc = flashSaveDecide;
3299
-  //renderLine = mode0RenderLine;
3300
-  fxOn = false;
3301
-  windowOn = false;
3302
-  frameCount = 0;
3303
-  saveType = 0;
3304
-  layerEnable = DISPCNT & layerSettings;
3305
-
3306
-  //CPUUpdateRenderBuffers(true);
3307
-
3308
-  for(int i = 0; i < 256; i++) {
3309
-    map[i].address = (uint8_t *)&dummyAddress;
3310
-    map[i].mask = 0;
3311
-  }
3312
-
3313
-  map[0].address = bios;
3314
-  map[0].mask = 0x3FFF;
3315
-  map[2].address = workRAM;
3316
-  map[2].mask = 0x3FFFF;
3317
-  map[3].address = internalRAM;
3318
-  map[3].mask = 0x7FFF;
3319
-  map[4].address = ioMem;
3320
-  map[4].mask = 0x3FF;
3321
-  map[5].address = paletteRAM;
3322
-  map[5].mask = 0x3FF;
3323
-  map[6].address = vram;
3324
-  map[6].mask = 0x1FFFF;
3325
-  map[7].address = oam;
3326
-  map[7].mask = 0x3FF;
3327
-  map[8].address = rom;
3328
-  map[8].mask = 0x1FFFFFF;
3329
-  map[9].address = rom;
3330
-  map[9].mask = 0x1FFFFFF;
3331
-  map[10].address = rom;
3332
-  map[10].mask = 0x1FFFFFF;
3333
-  map[12].address = rom;
3334
-  map[12].mask = 0x1FFFFFF;
3335
-  map[14].address = /*flashSaveMemory*/0;
3336
-  map[14].mask = 0xFFFF;
3337
-
3338
-  //eepromReset();
3339
-  //flashReset();
3340
-
3341
-  soundReset();
3342
-
3343
-  //CPUUpdateWindow0();
3344
-  //CPUUpdateWindow1();
3345
-
3346
-  // make sure registers are correctly initialized if not using BIOS
3347
-  if(!useBios) {
3348
-    if(cpuIsMultiBoot)
3349
-      BIOS_RegisterRamReset(0xfe);
3350
-    else
3351
-      BIOS_RegisterRamReset(0xff);
3352
-  } else {
3353
-    if(cpuIsMultiBoot)
3354
-      BIOS_RegisterRamReset(0xfe);
3355
-  }
3356
-
3357
-  /*switch(cpuSaveType) {
3358
-  case 0: // automatic
3359
-    cpuSramEnabled = true;
3360
-    cpuFlashEnabled = true;
3361
-    cpuEEPROMEnabled = true;
3362
-    cpuEEPROMSensorEnabled = false;
3363
-    saveType = gbaSaveType = 0;
3364
-    break;
3365
-  case 1: // EEPROM
3366
-    cpuSramEnabled = false;
3367
-    cpuFlashEnabled = false;
3368
-    cpuEEPROMEnabled = true;
3369
-    cpuEEPROMSensorEnabled = false;
3370
-    saveType = gbaSaveType = 3;
3371
-    // EEPROM usage is automatically detected
3372
-    break;
3373
-  case 2: // SRAM
3374
-    cpuSramEnabled = true;
3375
-    cpuFlashEnabled = false;
3376
-    cpuEEPROMEnabled = false;
3377
-    cpuEEPROMSensorEnabled = false;
3378
-    cpuSaveGameFunc = sramDelayedWrite; // to insure we detect the write
3379
-    saveType = gbaSaveType = 1;
3380
-    break;
3381
-  case 3: // FLASH
3382
-    cpuSramEnabled = false;
3383
-    cpuFlashEnabled = true;
3384
-    cpuEEPROMEnabled = false;
3385
-    cpuEEPROMSensorEnabled = false;
3386
-    cpuSaveGameFunc = flashDelayedWrite; // to insure we detect the write
3387
-    saveType = gbaSaveType = 2;
3388
-    break;
3389
-  case 4: // EEPROM+Sensor
3390
-    cpuSramEnabled = false;
3391
-    cpuFlashEnabled = false;
3392
-    cpuEEPROMEnabled = true;
3393
-    cpuEEPROMSensorEnabled = true;
3394
-    // EEPROM usage is automatically detected
3395
-    saveType = gbaSaveType = 3;
3396
-    break;
3397
-  case 5: // NONE
3398
-    cpuSramEnabled = false;
3399
-    cpuFlashEnabled = false;
3400
-    cpuEEPROMEnabled = false;
3401
-    cpuEEPROMSensorEnabled = false;
3402
-    // no save at all
3403
-    saveType = gbaSaveType = 5;
3404
-    break;
3405
-  }*/
3406
-
3407
-  ARM_PREFETCH;
3408
-
3409
-  //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
3410
-
3411
-  lastTime = /*systemGetClock()*/0;
3412
-
3413
-  SWITicks = 0;
1563
+	// clean registers
1564
+	memset(&reg[0], 0, sizeof(reg));
1565
+	// clean OAM
1566
+	memset(&oam[0], 0, 0x400);
1567
+	// clean palette
1568
+	memset(&paletteRAM[0], 0, 0x400);
1569
+	// clean vram
1570
+	memset(&vram[0], 0, 0x20000);
1571
+	// clean io memory
1572
+	memset(&ioMem[0], 0, 0x400);
1573
+
1574
+	DISPCNT = 0x0080;
1575
+	DISPSTAT = 0x0000;
1576
+	VCOUNT = 0x007E;
1577
+	BG0CNT = 0x0000;
1578
+	BG1CNT = 0x0000;
1579
+	BG2CNT = 0x0000;
1580
+	BG3CNT = 0x0000;
1581
+	BG0HOFS = 0x0000;
1582
+	BG0VOFS = 0x0000;
1583
+	BG1HOFS = 0x0000;
1584
+	BG1VOFS = 0x0000;
1585
+	BG2HOFS = 0x0000;
1586
+	BG2VOFS = 0x0000;
1587
+	BG3HOFS = 0x0000;
1588
+	BG3VOFS = 0x0000;
1589
+	BG2PA = 0x0100;
1590
+	BG2PB = 0x0000;
1591
+	BG2PC = 0x0000;
1592
+	BG2PD = 0x0100;
1593
+	BG2X_L = 0x0000;
1594
+	BG2X_H = 0x0000;
1595
+	BG2Y_L = 0x0000;
1596
+	BG2Y_H = 0x0000;
1597
+	BG3PA = 0x0100;
1598
+	BG3PB = 0x0000;
1599
+	BG3PC = 0x0000;
1600
+	BG3PD = 0x0100;
1601
+	BG3X_L = 0x0000;
1602
+	BG3X_H = 0x0000;
1603
+	BG3Y_L = 0x0000;
1604
+	BG3Y_H = 0x0000;
1605
+	WIN0H = 0x0000;
1606
+	WIN1H = 0x0000;
1607
+	WIN0V = 0x0000;
1608
+	WIN1V = 0x0000;
1609
+	WININ = 0x0000;
1610
+	WINOUT = 0x0000;
1611
+	MOSAIC = 0x0000;
1612
+	BLDMOD = 0x0000;
1613
+	COLEV = 0x0000;
1614
+	COLY = 0x0000;
1615
+	DM0SAD_L = 0x0000;
1616
+	DM0SAD_H = 0x0000;
1617
+	DM0DAD_L = 0x0000;
1618
+	DM0DAD_H = 0x0000;
1619
+	DM0CNT_L = 0x0000;
1620
+	DM0CNT_H = 0x0000;
1621
+	DM1SAD_L = 0x0000;
1622
+	DM1SAD_H = 0x0000;
1623
+	DM1DAD_L = 0x0000;
1624
+	DM1DAD_H = 0x0000;
1625
+	DM1CNT_L = 0x0000;
1626
+	DM1CNT_H = 0x0000;
1627
+	DM2SAD_L = 0x0000;
1628
+	DM2SAD_H = 0x0000;
1629
+	DM2DAD_L = 0x0000;
1630
+	DM2DAD_H = 0x0000;
1631
+	DM2CNT_L = 0x0000;
1632
+	DM2CNT_H = 0x0000;
1633
+	DM3SAD_L = 0x0000;
1634
+	DM3SAD_H = 0x0000;
1635
+	DM3DAD_L = 0x0000;
1636
+	DM3DAD_H = 0x0000;
1637
+	DM3CNT_L = 0x0000;
1638
+	DM3CNT_H = 0x0000;
1639
+	TM0D = 0x0000;
1640
+	TM0CNT = 0x0000;
1641
+	TM1D = 0x0000;
1642
+	TM1CNT = 0x0000;
1643
+	TM2D = 0x0000;
1644
+	TM2CNT = 0x0000;
1645
+	TM3D = 0x0000;
1646
+	TM3CNT = 0x0000;
1647
+	P1 = 0x03FF;
1648
+	IE = 0x0000;
1649
+	IF = 0x0000;
1650
+	IME = 0x0000;
1651
+
1652
+	armMode = 0x1F;
1653
+
1654
+	reg[13].I = 0x03007F00;
1655
+	reg[15].I = cpuIsMultiBoot ? 0x02000000 : 0x08000000;
1656
+	reg[16].I = 0x00000000;
1657
+	reg[R13_IRQ].I = 0x03007FA0;
1658
+	reg[R13_SVC].I = 0x03007FE0;
1659
+	armIrqEnable = true;
1660
+	armState = true;
1661
+	C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false;
1662
+	UPDATE_REG(0x00, DISPCNT);
1663
+	UPDATE_REG(0x06, VCOUNT);
1664
+	UPDATE_REG(0x20, BG2PA);
1665
+	UPDATE_REG(0x26, BG2PD);
1666
+	UPDATE_REG(0x30, BG3PA);
1667
+	UPDATE_REG(0x36, BG3PD);
1668
+	UPDATE_REG(0x130, P1);
1669
+	UPDATE_REG(0x88, 0x200);
1670
+
1671
+	// disable FIQ
1672
+	reg[16].I |= 0x40;
1673
+
1674
+	CPUUpdateCPSR();
1675
+
1676
+	armNextPC = reg[15].I;
1677
+	reg[15].I += 4;
1678
+
1679
+	// reset internal state
1680
+	holdState = false;
1681
+	holdType = 0;
1682
+
1683
+	biosProtected[0] = 0x00;
1684
+	biosProtected[1] = 0xf0;
1685
+	biosProtected[2] = 0x29;
1686
+	biosProtected[3] = 0xe1;
1687
+
1688
+	lcdTicks = 208;
1689
+	timer0On = false;
1690
+	timer0Ticks = 0;
1691
+	timer0Reload = 0;
1692
+	timer0ClockReload  = 0;
1693
+	timer1On = false;
1694
+	timer1Ticks = 0;
1695
+	timer1Reload = 0;
1696
+	timer1ClockReload  = 0;
1697
+	timer2On = false;
1698
+	timer2Ticks = 0;
1699
+	timer2Reload = 0;
1700
+	timer2ClockReload  = 0;
1701
+	timer3On = false;
1702
+	timer3Ticks = 0;
1703
+	timer3Reload = 0;
1704
+	timer3ClockReload  = 0;
1705
+	dma0Source = 0;
1706
+	dma0Dest = 0;
1707
+	dma1Source = 0;
1708
+	dma1Dest = 0;
1709
+	dma2Source = 0;
1710
+	dma2Dest = 0;
1711
+	dma3Source = 0;
1712
+	dma3Dest = 0;
1713
+	layerEnable = DISPCNT & layerSettings;
1714
+
1715
+	for (int i = 0; i < 256; ++i)
1716
+	{
1717
+		map[i].address = reinterpret_cast<uint8_t *>(&dummyAddress);
1718
+		map[i].mask = 0;
1719
+	}
1720
+
1721
+	map[0].address = &bios[0];
1722
+	map[0].mask = 0x3FFF;
1723
+	map[2].address = &workRAM[0];
1724
+	map[2].mask = 0x3FFFF;
1725
+	map[3].address = &internalRAM[0];
1726
+	map[3].mask = 0x7FFF;
1727
+	map[4].address = ioMem;
1728
+	map[4].mask = 0x3FF;
1729
+	map[5].address = &paletteRAM[0];
1730
+	map[5].mask = 0x3FF;
1731
+	map[6].address = &vram[0];
1732
+	map[6].mask = 0x1FFFF;
1733
+	map[7].address = &oam[0];
1734
+	map[7].mask = 0x3FF;
1735
+	map[8].address = &rom[0];
1736
+	map[8].mask = 0x1FFFFFF;
1737
+	map[9].address = &rom[0];
1738
+	map[9].mask = 0x1FFFFFF;
1739
+	map[10].address = &rom[0];
1740
+	map[10].mask = 0x1FFFFFF;
1741
+	map[12].address = &rom[0];
1742
+	map[12].mask = 0x1FFFFFF;
1743
+
1744
+	soundReset();
1745
+
1746
+	// make sure registers are correctly initialized if not using BIOS
1747
+	BIOS_RegisterRamReset(cpuIsMultiBoot ? 0xfe : 0xff);
1748
+
1749
+	ARM_PREFETCH();
1750
+
1751
+	SWITicks = 0;
3414 1752
 }
3415 1753
 
3416 1754
 void CPUInterrupt()
3417 1755
 {
3418
-  uint32_t PC = reg[15].I;
3419
-  bool savedState = armState;
3420
-  CPUSwitchMode(0x12, true, false);
3421
-  reg[14].I = PC;
3422
-  if(!savedState)
3423
-    reg[14].I += 2;
3424
-  reg[15].I = 0x18;
3425
-  armState = true;
3426
-  armIrqEnable = false;
3427
-
3428
-  armNextPC = reg[15].I;
3429
-  reg[15].I += 4;
3430
-  ARM_PREFETCH;
3431
-
3432
-  //  if(!holdState)
3433
-  biosProtected[0] = 0x02;
3434
-  biosProtected[1] = 0xc0;
3435
-  biosProtected[2] = 0x5e;
3436
-  biosProtected[3] = 0xe5;
1756
+	uint32_t PC = reg[15].I;
1757
+	bool savedState = armState;
1758
+	CPUSwitchMode(0x12, true, false);
1759
+	reg[14].I = PC;
1760
+	if (!savedState)
1761
+		reg[14].I += 2;
1762
+	reg[15].I = 0x18;
1763
+	armState = true;
1764
+	armIrqEnable = false;
1765
+
1766
+	armNextPC = reg[15].I;
1767
+	reg[15].I += 4;
1768
+	ARM_PREFETCH();
1769
+
1770
+	//if(!holdState)
1771
+	biosProtected[0] = 0x02;
1772
+	biosProtected[1] = 0xc0;
1773
+	biosProtected[2] = 0x5e;
1774
+	biosProtected[3] = 0xe5;
3437 1775
 }
3438 1776
 
3439 1777
 void CPULoop(int ticks)
3440 1778
 {
3441
-  int clockTicks;
3442
-  int timerOverflow = 0;
3443
-  // variable used by the CPU core
3444
-  cpuTotalTicks = 0;
3445
-
3446
-  // shuffle2: what's the purpose?
3447
-  /*if(gba_link_enabled)
3448
-    cpuNextEvent = 1;*/
3449
-
3450
-  cpuBreakLoop = false;
3451
-  cpuNextEvent = CPUUpdateTicks();
3452
-  if(cpuNextEvent > ticks)
3453
-    cpuNextEvent = ticks;
3454
-
3455
-
3456
-  for(;;) {
3457
-#ifndef FINAL_VERSION
3458
-    if(systemDebug) {
3459
-      if(systemDebug >= 10 && !holdState) {
3460
-        CPUUpdateCPSR();
3461
-#ifdef BKPT_SUPPORT
3462
-		if (debugger_last)
1779
+	int clockTicks;
1780
+	int timerOverflow = 0;
1781
+	// variable used by the CPU core
1782
+	cpuTotalTicks = 0;
1783
+
1784
+	cpuNextEvent = CPUUpdateTicks();
1785
+	if (cpuNextEvent > ticks)
1786
+		cpuNextEvent = ticks;
1787
+
1788
+	for (;;)
1789
+	{
1790
+		if (!holdState && !SWITicks)
3463 1791
 		{
3464
-		winlog("R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
3465
-                 oldreg[0], oldreg[1], oldreg[2], oldreg[3], oldreg[4], oldreg[5],
3466
-                 oldreg[6], oldreg[7], oldreg[8], oldreg[9], oldreg[10], oldreg[11],
3467
-                 oldreg[12], oldreg[13], oldreg[14], oldreg[15], oldreg[16],
3468
-                 oldreg[17]);
1792
+			if (armState)
1793
+			{
1794
+				if (!armExecute())
1795
+					return;
1796
+			}
1797
+			else
1798
+			{
1799
+				if (!thumbExecute())
1800
+					return;
1801
+			}
1802
+			clockTicks = 0;
3469 1803
 		}
3470
-#endif
3471
-        winlog("R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
3472
-                 reg[0].I, reg[1].I, reg[2].I, reg[3].I, reg[4].I, reg[5].I,
3473
-                 reg[6].I, reg[7].I, reg[8].I, reg[9].I, reg[10].I, reg[11].I,
3474
-                 reg[12].I, reg[13].I, reg[14].I, reg[15].I, reg[16].I,
3475
-                 reg[17].I);
3476
-      } else if(!holdState) {
3477
-        winlog("PC=%08x\n", armNextPC);
3478
-      }
3479
-    }
3480
-#endif /* FINAL_VERSION */
3481
-
3482
-    if(!holdState && !SWITicks) {
3483
-      if(armState) {
3484
-        if (!armExecute())
3485
-          return;
3486
-      } else {
3487
-        if (!thumbExecute())
3488
-          return;
3489
-      }
3490
-      clockTicks = 0;
3491
-    } else
3492
-      clockTicks = CPUUpdateTicks();
3493
-
3494
-    cpuTotalTicks += clockTicks;
3495
-
3496
-
3497
-    if(cpuTotalTicks >= cpuNextEvent) {
3498
-      int remainingTicks = cpuTotalTicks - cpuNextEvent;
3499
-
3500
-      if (SWITicks)
3501
-      {
3502
-        SWITicks-=clockTicks;
3503
-        if (SWITicks<0)
3504
-          SWITicks = 0;
3505
-      }
3506
-
3507
-      clockTicks = cpuNextEvent;
3508
-      cpuTotalTicks = 0;
3509
-
3510
-    updateLoop:
3511
-
3512
-      if (IRQTicks)
3513
-      {
3514
-          IRQTicks -= clockTicks;
3515
-        if (IRQTicks<0)
3516
-          IRQTicks = 0;
3517
-      }
3518
-
3519
-      lcdTicks -= clockTicks;
3520
-
3521
-
3522
-      if(lcdTicks <= 0) {
3523
-        if(DISPSTAT & 1) { // V-BLANK
3524
-          // if in V-Blank mode, keep computing...
3525
-          if(DISPSTAT & 2) {
3526
-            lcdTicks += 1008;
3527
-            VCOUNT++;
3528
-            UPDATE_REG(0x06, VCOUNT);
3529
-            DISPSTAT &= 0xFFFD;
3530
-            UPDATE_REG(0x04, DISPSTAT);
3531
-            CPUCompareVCOUNT();
3532
-          } else {
3533
-            lcdTicks += 224;
3534
-            DISPSTAT |= 2;
3535
-            UPDATE_REG(0x04, DISPSTAT);
3536
-            if(DISPSTAT & 16) {
3537
-              IF |= 2;
3538
-              UPDATE_REG(0x202, IF);
3539
-            }
3540
-          }
3541
-
3542
-          if(VCOUNT >= 228) { //Reaching last line
3543
-            DISPSTAT &= 0xFFFC;
3544
-            UPDATE_REG(0x04, DISPSTAT);
3545
-            VCOUNT = 0;
3546
-            UPDATE_REG(0x06, VCOUNT);
3547
-            CPUCompareVCOUNT();
3548
-          }
3549
-        } else {
3550
-          /*int framesToSkip = *//*systemFrameSkip*//*0;
3551
-          if(speedup)
3552
-            framesToSkip = 9;*/ // try 6 FPS during speedup
3553
-
3554
-          if(DISPSTAT & 2) {
3555
-            // if in H-Blank, leave it and move to drawing mode
3556
-            VCOUNT++;
3557
-            UPDATE_REG(0x06, VCOUNT);
3558
-
3559
-            lcdTicks += 1008;
3560
-            DISPSTAT &= 0xFFFD;
3561
-            if(VCOUNT == 160) {
3562
-              count++;
3563
-              //systemFrame();
3564
-
3565
-              /*if((count % 10) == 0) {
3566
-                //system10Frames(60);
3567
-              }*/
3568
-              if(count == 60) {
3569
-                /*u32 time = *//*systemGetClock()*//*0;
3570
-                if(time != lastTime) {
3571
-                  //u32 t = 100000/(time - lastTime);
3572
-                  //systemShowSpeed(t);
3573
-                } else
3574
-                  //systemShowSpeed(0);
3575
-                lastTime = time;*/
3576
-                count = 0;
3577
-              }
3578
-              //u32 joy = 0;
3579
-              // update joystick information
3580
-              /*if(systemReadJoypads())
3581
-                // read default joystick
3582
-                joy = systemReadJoypad(-1);*/
3583
-              //P1 = 0x03FF ^ (joy & 0x3FF);
3584
-              /*if(cpuEEPROMSensorEnabled)
3585
-                systemUpdateMotionSensor();*/
3586
-              /*UPDATE_REG(0x130, P1);
3587
-              u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132]));
3588
-              // this seems wrong, but there are cases where the game
3589
-              // can enter the stop state without requesting an IRQ from
3590
-              // the joypad.
3591
-              if((P1CNT & 0x4000) || stopState) {
3592
-                u16 p1 = (0x3FF ^ P1) & 0x3FF;
3593
-                if(P1CNT & 0x8000) {
3594
-                  if(p1 == (P1CNT & 0x3FF)) {
3595
-                    IF |= 0x1000;
3596
-                    UPDATE_REG(0x202, IF);
3597
-                  }
3598
-                } else {
3599
-                  if(p1 & P1CNT) {
3600
-                    IF |= 0x1000;
3601
-                    UPDATE_REG(0x202, IF);
3602
-                  }
3603
-                }
3604
-              }
3605
-
3606
-              u32 ext = (joy >> 10);*/
3607
-              // If no (m) code is enabled, apply the cheats at each LCDline
3608
-              /*if((cheatsEnabled) && (mastercode==0))
3609
-                remainingTicks += cheatsCheckKeys(P1^0x3FF, ext);*/
3610
-              /*speedup = (ext & 1) ? true : false;
3611
-              capture = (ext & 2) ? true : false;
3612
-
3613
-              if(capture && !capturePrevious) {
3614
-                captureNumber++;
3615
-                //systemScreenCapture(captureNumber);
3616
-              }
3617
-              capturePrevious = capture;*/
3618
-
3619
-              DISPSTAT |= 1;
3620
-              DISPSTAT &= 0xFFFD;
3621
-              UPDATE_REG(0x04, DISPSTAT);
3622
-              if(DISPSTAT & 0x0008) {
3623
-                IF |= 1;
3624
-                UPDATE_REG(0x202, IF);
3625
-              }
3626
-              CPUCheckDMA(1, 0x0f);
3627
-              /*if(frameCount >= framesToSkip) {
3628
-                //systemDrawScreen();
3629
-                frameCount = 0;
3630
-              } else*/
3631
-                frameCount++;
3632
-              /*if(systemPauseOnFrame())
3633
-                ticks = 0;*/
3634
-            }
3635
-
3636
-            UPDATE_REG(0x04, DISPSTAT);
3637
-            CPUCompareVCOUNT();
3638
-
3639
-          } else {
3640
-            /*if(frameCount >= framesToSkip)
3641
-            {*/
3642
-              /*(*renderLine)();
3643
-              switch(systemColorDepth) {
3644
-                case 16:
3645
-                {
3646
-                  u16 *dest = (u16 *)pix + 242 * (VCOUNT+1);
3647
-                  for(int x = 0; x < 240;) {
3648
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3649
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3650
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3651
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3652
-
3653
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3654
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3655
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3656
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3657
-
3658
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3659
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3660
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3661
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3662
-
3663
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3664
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3665
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3666
-                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3667
-                  }
3668
-                  // for filters that read past the screen
3669
-                  *dest++ = 0;
3670
-                }
3671
-                break;
3672
-                case 24:
3673
-                {
3674
-                  u8 *dest = (u8 *)pix + 240 * VCOUNT * 3;
3675
-                  for(int x = 0; x < 240;) {
3676
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3677
-                    dest += 3;
3678
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3679
-                    dest += 3;
3680
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3681
-                    dest += 3;
3682
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3683
-                    dest += 3;
3684
-
3685
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3686
-                    dest += 3;
3687
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3688
-                    dest += 3;
3689
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3690
-                    dest += 3;
3691
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3692
-                    dest += 3;
3693
-
3694
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3695
-                    dest += 3;
3696
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3697
-                    dest += 3;
3698
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3699
-                    dest += 3;
3700
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3701
-                    dest += 3;
3702
-
3703
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3704
-                    dest += 3;
3705
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3706
-                    dest += 3;
3707
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3708
-                    dest += 3;
3709
-                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3710
-                    dest += 3;
3711
-                  }
3712
-                }
3713
-                break;
3714
-                case 32:
3715
-                {
3716
-                  u32 *dest = (u32 *)pix + 241 * (VCOUNT+1);
3717
-                  for(int x = 0; x < 240; ) {
3718
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3719
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3720
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3721
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3722
-
3723
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3724
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3725
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3726
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3727
-
3728
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3729
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3730
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3731
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3732
-
3733
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3734
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3735
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3736
-                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3737
-                  }
3738
-                }
3739
-                break;
3740
-              }*/
3741
-            /*}*/
3742
-            // entering H-Blank
3743
-            DISPSTAT |= 2;
3744
-            UPDATE_REG(0x04, DISPSTAT);
3745
-            lcdTicks += 224;
3746
-            CPUCheckDMA(2, 0x0f);
3747
-            if(DISPSTAT & 16) {
3748
-              IF |= 2;
3749
-              UPDATE_REG(0x202, IF);
3750
-            }
3751
-          }
3752
-        }
3753
-      }
3754
-
3755
-	    // we shouldn't be doing sound in stop state, but we loose synchronization
3756
-      // if sound is disabled, so in stop state, soundTick will just produce
3757
-      // mute sound
3758
-      soundTicks -= clockTicks;
3759
-      if(soundTicks <= 0) {
3760
-        psoundTickfn();
3761
-        soundTicks += SOUND_CLOCK_TICKS;
3762
-      }
3763
-
3764
-      if(!stopState) {
3765
-        if(timer0On) {
3766
-          timer0Ticks -= clockTicks;
3767
-          if(timer0Ticks <= 0) {
3768
-            timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload;
3769
-            timerOverflow |= 1;
3770
-            soundTimerOverflow(0);
3771
-            if(TM0CNT & 0x40) {
3772
-              IF |= 0x08;
3773
-              UPDATE_REG(0x202, IF);
3774
-            }
3775
-          }
3776
-          TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload);
3777
-          UPDATE_REG(0x100, TM0D);
3778
-        }
3779
-
3780
-        if(timer1On) {
3781
-          if(TM1CNT & 4) {
3782
-            if(timerOverflow & 1) {
3783
-              TM1D++;
3784
-              if(TM1D == 0) {
3785
-                TM1D += timer1Reload;
3786
-                timerOverflow |= 2;
3787
-                soundTimerOverflow(1);
3788
-                if(TM1CNT & 0x40) {
3789
-                  IF |= 0x10;
3790
-                  UPDATE_REG(0x202, IF);
3791
-                }
3792
-              }
3793
-              UPDATE_REG(0x104, TM1D);
3794
-            }
3795
-          } else {
3796
-            timer1Ticks -= clockTicks;
3797
-            if(timer1Ticks <= 0) {
3798
-              timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload;
3799
-              timerOverflow |= 2;
3800
-              soundTimerOverflow(1);
3801
-              if(TM1CNT & 0x40) {
3802
-                IF |= 0x10;
3803
-                UPDATE_REG(0x202, IF);
3804
-              }
3805
-            }
3806
-            TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload);
3807
-            UPDATE_REG(0x104, TM1D);
3808
-          }
3809
-        }
3810
-
3811
-        if(timer2On) {
3812
-          if(TM2CNT & 4) {
3813
-            if(timerOverflow & 2) {
3814
-              TM2D++;
3815
-              if(TM2D == 0) {
3816
-                TM2D += timer2Reload;
3817
-                timerOverflow |= 4;
3818
-                if(TM2CNT & 0x40) {
3819
-                  IF |= 0x20;
3820
-                  UPDATE_REG(0x202, IF);
3821
-                }
3822
-              }
3823
-              UPDATE_REG(0x108, TM2D);
3824
-            }
3825
-          } else {
3826
-            timer2Ticks -= clockTicks;
3827
-            if(timer2Ticks <= 0) {
3828
-              timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload;
3829
-              timerOverflow |= 4;
3830
-              if(TM2CNT & 0x40) {
3831
-                IF |= 0x20;
3832
-                UPDATE_REG(0x202, IF);
3833
-              }
3834
-            }
3835
-            TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload);
3836
-            UPDATE_REG(0x108, TM2D);
3837
-          }
3838
-        }
3839
-
3840
-        if(timer3On) {
3841
-          if(TM3CNT & 4) {
3842
-            if(timerOverflow & 4) {
3843
-              TM3D++;
3844
-              if(TM3D == 0) {
3845
-                TM3D += timer3Reload;
3846
-                if(TM3CNT & 0x40) {
3847
-                  IF |= 0x40;
3848
-                  UPDATE_REG(0x202, IF);
3849
-                }
3850
-              }
3851
-              UPDATE_REG(0x10C, TM3D);
3852
-            }
3853
-          } else {
3854
-              timer3Ticks -= clockTicks;
3855
-            if(timer3Ticks <= 0) {
3856
-              timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload;
3857
-              if(TM3CNT & 0x40) {
3858
-                IF |= 0x40;
3859
-                UPDATE_REG(0x202, IF);
3860
-              }
3861
-            }
3862
-            TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload);
3863
-            UPDATE_REG(0x10C, TM3D);
3864
-          }
3865
-        }
3866
-      }
3867
-
3868
-      timerOverflow = 0;
3869
-
3870
-
3871
-
3872
-#ifdef PROFILING
3873
-      profilingTicks -= clockTicks;
3874
-      if(profilingTicks <= 0) {
3875
-        profilingTicks += profilingTicksReload;
3876
-        if(profilSegment) {
3877
-	  profile_segment *seg = profilSegment;
3878
-	  do {
3879
-	    uint16_t *b = (uint16_t *)seg->sbuf;
3880
-	    int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale)/0x10000;
3881
-	    if(pc >= 0 && pc < seg->ssiz) {
3882
-            b[pc]++;
3883
-	      break;
3884
-          }
3885
-
3886
-	    seg = seg->next;
3887
-	  } while(seg);
3888
-        }
3889
-      }
3890
-#endif
1804
+		else
1805
+			clockTicks = CPUUpdateTicks();
3891 1806
 
3892
-      ticks -= clockTicks;
3893
-
3894
-	  /*if (gba_joybus_enabled)
3895
-		  JoyBusUpdate(clockTicks);
3896
-
3897
-	  if (gba_link_enabled)
3898
-		  LinkUpdate(clockTicks);*/
3899
-
3900
-      cpuNextEvent = CPUUpdateTicks();
3901
-
3902
-      if(cpuDmaTicksToUpdate > 0) {
3903
-        if(cpuDmaTicksToUpdate > cpuNextEvent)
3904
-          clockTicks = cpuNextEvent;
3905
-        else
3906
-          clockTicks = cpuDmaTicksToUpdate;
3907
-        cpuDmaTicksToUpdate -= clockTicks;
3908
-        if(cpuDmaTicksToUpdate < 0)
3909
-          cpuDmaTicksToUpdate = 0;
3910
-        goto updateLoop;
3911
-      }
3912
-
3913
-	  // shuffle2: what's the purpose?
3914
-	  /*if(gba_link_enabled)
3915
-  	       cpuNextEvent = 1;*/
3916
-
3917
-      if(IF && (IME & 1) && armIrqEnable) {
3918
-        int res = IF & IE;
3919
-        if(stopState)
3920
-          res &= 0x3080;
3921
-        if(res) {
3922
-          if (intState)
3923
-          {
3924
-            if (!IRQTicks)
3925
-            {
3926
-              CPUInterrupt();
3927
-              intState = false;
3928
-              holdState = false;
3929
-              stopState = false;
3930
-              holdType = 0;
3931
-            }
3932
-          }
3933
-          else
3934
-          {
3935
-            if (!holdState)
3936
-            {
3937
-              intState = true;
3938
-              IRQTicks=7;
3939
-              if (cpuNextEvent> IRQTicks)
3940
-                cpuNextEvent = IRQTicks;
3941
-            }
3942
-            else
3943
-            {
3944
-              CPUInterrupt();
3945
-              holdState = false;
3946
-              stopState = false;
3947
-              holdType = 0;
3948
-            }
3949
-          }
3950
-
3951
-          // Stops the SWI Ticks emulation if an IRQ is executed
3952
-          //(to avoid problems with nested IRQ/SWI)
3953
-          if (SWITicks)
3954
-            SWITicks = 0;
3955
-        }
3956
-      }
3957
-
3958
-      if(remainingTicks > 0) {
3959
-        if(remainingTicks > cpuNextEvent)
3960
-          clockTicks = cpuNextEvent;
3961
-        else
3962
-          clockTicks = remainingTicks;
3963
-        remainingTicks -= clockTicks;
3964
-        if(remainingTicks < 0)
3965
-          remainingTicks = 0;
3966
-        goto updateLoop;
3967
-      }
3968
-
3969
-      if (timerOnOffDelay)
3970
-          applyTimer();
3971
-
3972
-      if(cpuNextEvent > ticks)
3973
-        cpuNextEvent = ticks;
3974
-
3975
-      if(ticks <= 0 || cpuBreakLoop)
3976
-        break;
3977
-
3978
-    }
3979
-  }
3980
-}
1807
+		cpuTotalTicks += clockTicks;
3981 1808
 
3982
-
3983
-
3984
-/*struct EmulatedSystem GBASystem = {
3985
-  // emuMain
3986
-  CPULoop,
3987
-  // emuReset
3988
-  CPUReset,
3989
-  // emuCleanUp
3990
-  CPUCleanUp,
3991
-  // emuReadBattery
3992
-  CPUReadBatteryFile,
3993
-  // emuWriteBattery
3994
-  CPUWriteBatteryFile,
3995
-  // emuReadState
3996
-  CPUReadState,
3997
-  // emuWriteState
3998
-  CPUWriteState,
3999
-  // emuReadMemState
4000
-  CPUReadMemState,
4001
-  // emuWriteMemState
4002
-  CPUWriteMemState,
4003
-  // emuWritePNG
4004
-  CPUWritePNGFile,
4005
-  // emuWriteBMP
4006
-  CPUWriteBMPFile,
4007
-  // emuUpdateCPSR
4008
-  CPUUpdateCPSR,
4009
-  // emuHasDebugger
4010
-  true,
4011
-  // emuCount
4012
-#ifdef FINAL_VERSION
4013
-  250000
4014
-#else
4015
-  5000
4016
-#endif
4017
-};*/
1809
+		if (cpuTotalTicks >= cpuNextEvent)
1810
+		{
1811
+			int remainingTicks = cpuTotalTicks - cpuNextEvent;
1812
+
1813
+			if (SWITicks)
1814
+			{
1815
+				SWITicks -= clockTicks;
1816
+				if (SWITicks < 0)
1817
+					SWITicks = 0;
1818
+			}
1819
+
1820
+			clockTicks = cpuNextEvent;
1821
+			cpuTotalTicks = 0;
1822
+
1823
+		updateLoop:
1824
+
1825
+			if (IRQTicks)
1826
+			{
1827
+				IRQTicks -= clockTicks;
1828
+				if (IRQTicks < 0)
1829
+					IRQTicks = 0;
1830
+			}
1831
+
1832
+			lcdTicks -= clockTicks;
1833
+
1834
+			if (lcdTicks <= 0)
1835
+			{
1836
+				if (DISPSTAT & 1) // V-BLANK
1837
+				{
1838
+					// if in V-Blank mode, keep computing...
1839
+					if (DISPSTAT & 2)
1840
+					{
1841
+						lcdTicks += 1008;
1842
+						++VCOUNT;
1843
+						UPDATE_REG(0x06, VCOUNT);
1844
+						DISPSTAT &= 0xFFFD;
1845
+						UPDATE_REG(0x04, DISPSTAT);
1846
+						CPUCompareVCOUNT();
1847
+					}
1848
+					else
1849
+					{
1850
+						lcdTicks += 224;
1851
+						DISPSTAT |= 2;
1852
+						UPDATE_REG(0x04, DISPSTAT);
1853
+						if (DISPSTAT & 16)
1854
+						{
1855
+							IF |= 2;
1856
+							UPDATE_REG(0x202, IF);
1857
+						}
1858
+					}
1859
+
1860
+					if (VCOUNT >= 228) //Reaching last line
1861
+					{
1862
+						DISPSTAT &= 0xFFFC;
1863
+						UPDATE_REG(0x04, DISPSTAT);
1864
+						VCOUNT = 0;
1865
+						UPDATE_REG(0x06, VCOUNT);
1866
+						CPUCompareVCOUNT();
1867
+					}
1868
+				}
1869
+				else
1870
+				{
1871
+					if (DISPSTAT & 2)
1872
+					{
1873
+						// if in H-Blank, leave it and move to drawing mode
1874
+						++VCOUNT;
1875
+						UPDATE_REG(0x06, VCOUNT);
1876
+
1877
+						lcdTicks += 1008;
1878
+						DISPSTAT &= 0xFFFD;
1879
+						if (VCOUNT == 160)
1880
+						{
1881
+							++count;
1882
+							if (count == 60)
1883
+								count = 0;
1884
+
1885
+							DISPSTAT |= 1;
1886
+							DISPSTAT &= 0xFFFD;
1887
+							UPDATE_REG(0x04, DISPSTAT);
1888
+							if (DISPSTAT & 0x0008)
1889
+							{
1890
+								IF |= 1;
1891
+								UPDATE_REG(0x202, IF);
1892
+							}
1893
+							CPUCheckDMA(1, 0x0f);
1894
+						}
1895
+
1896
+						UPDATE_REG(0x04, DISPSTAT);
1897
+						CPUCompareVCOUNT();
1898
+					}
1899
+					else
1900
+					{
1901
+						// entering H-Blank
1902
+						DISPSTAT |= 2;
1903
+						UPDATE_REG(0x04, DISPSTAT);
1904
+						lcdTicks += 224;
1905
+						CPUCheckDMA(2, 0x0f);
1906
+						if (DISPSTAT & 16)
1907
+						{
1908
+							IF |= 2;
1909
+							UPDATE_REG(0x202, IF);
1910
+						}
1911
+					}
1912
+				}
1913
+			}
1914
+
1915
+			// we shouldn't be doing sound in stop state, but we loose synchronization
1916
+			// if sound is disabled, so in stop state, soundTick will just produce
1917
+			// mute sound
1918
+			soundTicks -= clockTicks;
1919
+			if (soundTicks <= 0)
1920
+			{
1921
+				psoundTickfn();
1922
+				soundTicks += SOUND_CLOCK_TICKS;
1923
+			}
1924
+
1925
+			if (!stopState)
1926
+			{
1927
+				if (timer0On)
1928
+				{
1929
+					timer0Ticks -= clockTicks;
1930
+					if (timer0Ticks <= 0)
1931
+					{
1932
+						timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload;
1933
+						timerOverflow |= 1;
1934
+						soundTimerOverflow(0);
1935
+						if (TM0CNT & 0x40)
1936
+						{
1937
+							IF |= 0x08;
1938
+							UPDATE_REG(0x202, IF);
1939
+						}
1940
+					}
1941
+					TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload);
1942
+					UPDATE_REG(0x100, TM0D);
1943
+				}
1944
+
1945
+				if (timer1On)
1946
+				{
1947
+					if (TM1CNT & 4)
1948
+					{
1949
+						if (timerOverflow & 1)
1950
+						{
1951
+							++TM1D;
1952
+							if (!TM1D)
1953
+							{
1954
+								TM1D += timer1Reload;
1955
+								timerOverflow |= 2;
1956
+								soundTimerOverflow(1);
1957
+								if (TM1CNT & 0x40)
1958
+								{
1959
+									IF |= 0x10;
1960
+									UPDATE_REG(0x202, IF);
1961
+								}
1962
+							}
1963
+							UPDATE_REG(0x104, TM1D);
1964
+						}
1965
+					}
1966
+					else
1967
+					{
1968
+						timer1Ticks -= clockTicks;
1969
+						if (timer1Ticks <= 0)
1970
+						{
1971
+							timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload;
1972
+							timerOverflow |= 2;
1973
+							soundTimerOverflow(1);
1974
+							if (TM1CNT & 0x40)
1975
+							{
1976
+								IF |= 0x10;
1977
+								UPDATE_REG(0x202, IF);
1978
+							}
1979
+						}
1980
+						TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload);
1981
+						UPDATE_REG(0x104, TM1D);
1982
+					}
1983
+				}
1984
+
1985
+				if (timer2On)
1986
+				{
1987
+					if (TM2CNT & 4)
1988
+					{
1989
+						if (timerOverflow & 2)
1990
+						{
1991
+							++TM2D;
1992
+							if (!TM2D)
1993
+							{
1994
+								TM2D += timer2Reload;
1995
+								timerOverflow |= 4;
1996
+								if (TM2CNT & 0x40)
1997
+								{
1998
+									IF |= 0x20;
1999
+									UPDATE_REG(0x202, IF);
2000
+								}
2001
+							}
2002
+							UPDATE_REG(0x108, TM2D);
2003
+						}
2004
+					}
2005
+					else
2006
+					{
2007
+						timer2Ticks -= clockTicks;
2008
+						if (timer2Ticks <= 0)
2009
+						{
2010
+							timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload;
2011
+							timerOverflow |= 4;
2012
+							if (TM2CNT & 0x40)
2013
+							{
2014
+								IF |= 0x20;
2015
+								UPDATE_REG(0x202, IF);
2016
+							}
2017
+						}
2018
+						TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload);
2019
+						UPDATE_REG(0x108, TM2D);
2020
+					}
2021
+				}
2022
+
2023
+				if (timer3On)
2024
+				{
2025
+					if (TM3CNT & 4)
2026
+					{
2027
+						if (timerOverflow & 4)
2028
+						{
2029
+							++TM3D;
2030
+							if (!TM3D)
2031
+							{
2032
+								TM3D += timer3Reload;
2033
+								if (TM3CNT & 0x40)
2034
+								{
2035
+									IF |= 0x40;
2036
+									UPDATE_REG(0x202, IF);
2037
+								}
2038
+							}
2039
+							UPDATE_REG(0x10C, TM3D);
2040
+						}
2041
+					}
2042
+					else
2043
+					{
2044
+						timer3Ticks -= clockTicks;
2045
+						if (timer3Ticks <= 0)
2046
+						{
2047
+							timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload;
2048
+							if (TM3CNT & 0x40)
2049
+							{
2050
+								IF |= 0x40;
2051
+								UPDATE_REG(0x202, IF);
2052
+							}
2053
+						}
2054
+						TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload);
2055
+						UPDATE_REG(0x10C, TM3D);
2056
+					}
2057
+				}
2058
+			}
2059
+
2060
+			timerOverflow = 0;
2061
+
2062
+			ticks -= clockTicks;
2063
+
2064
+			cpuNextEvent = CPUUpdateTicks();
2065
+
2066
+			if (cpuDmaTicksToUpdate > 0)
2067
+			{
2068
+				if (cpuDmaTicksToUpdate > cpuNextEvent)
2069
+					clockTicks = cpuNextEvent;
2070
+				else
2071
+					clockTicks = cpuDmaTicksToUpdate;
2072
+				cpuDmaTicksToUpdate -= clockTicks;
2073
+				if (cpuDmaTicksToUpdate < 0)
2074
+					cpuDmaTicksToUpdate = 0;
2075
+				goto updateLoop;
2076
+			}
2077
+
2078
+			if (IF && (IME & 1) && armIrqEnable)
2079
+			{
2080
+				int res = IF & IE;
2081
+				if (stopState)
2082
+					res &= 0x3080;
2083
+				if (res)
2084
+				{
2085
+					if (intState)
2086
+					{
2087
+						if (!IRQTicks)
2088
+						{
2089
+							CPUInterrupt();
2090
+							intState = false;
2091
+							holdState = false;
2092
+							stopState = false;
2093
+							holdType = 0;
2094
+						}
2095
+					}
2096
+					else
2097
+					{
2098
+						if (!holdState)
2099
+						{
2100
+							intState = true;
2101
+							IRQTicks = 7;
2102
+							if (cpuNextEvent> IRQTicks)
2103
+								cpuNextEvent = IRQTicks;
2104
+						}
2105
+						else
2106
+						{
2107
+							CPUInterrupt();
2108
+							holdState = false;
2109
+							stopState = false;
2110
+							holdType = 0;
2111
+						}
2112
+					}
2113
+
2114
+					// Stops the SWI Ticks emulation if an IRQ is executed
2115
+					// (to avoid problems with nested IRQ/SWI)
2116
+					if (SWITicks)
2117
+						SWITicks = 0;
2118
+				}
2119
+			}
2120
+
2121
+			if (remainingTicks > 0)
2122
+			{
2123
+				if (remainingTicks > cpuNextEvent)
2124
+					clockTicks = cpuNextEvent;
2125
+				else
2126
+					clockTicks = remainingTicks;
2127
+				remainingTicks -= clockTicks;
2128
+				if (remainingTicks < 0)
2129
+					remainingTicks = 0;
2130
+				goto updateLoop;
2131
+			}
2132
+
2133
+			if (timerOnOffDelay)
2134
+				applyTimer();
2135
+
2136
+			if (cpuNextEvent > ticks)
2137
+				cpuNextEvent = ticks;
2138
+
2139
+			if (ticks <= 0)
2140
+				break;
2141
+		}
2142
+	}
2143
+}
Browse code

[GSF] Cleanup, a tiny bit of making sure it was like viogsf, also used the standard integer types and not VBA-M's typedefs.

Naram Qashat authored on 2013/05/10 17:45:36
Showing 1 changed files
... ...
@@ -22,7 +22,7 @@
22 22
 //#include "agbprint.h"
23 23
 //#include "GBALink.h"
24 24
 
25
-extern int mapgsf(u8* a, int l, int &s);
25
+extern int mapgsf(uint8_t* a, int l, int &s);
26 26
 
27 27
 #ifdef PROFILING
28 28
 #include "prof/prof.h"
... ...
@@ -37,14 +37,14 @@ extern int emulating;
37 37
 int SWITicks = 0;
38 38
 int IRQTicks = 0;
39 39
 
40
-u32 mastercode = 0;
40
+uint32_t mastercode = 0;
41 41
 int layerEnableDelay = 0;
42 42
 bool busPrefetch = false;
43 43
 bool busPrefetchEnable = false;
44
-u32 busPrefetchCount = 0;
44
+uint32_t busPrefetchCount = 0;
45 45
 int cpuDmaTicksToUpdate = 0;
46 46
 int cpuDmaCount = 0;
47
-u32 cpuDmaLast = 0;
47
+uint32_t cpuDmaLast = 0;
48 48
 int dummyAddress = 0;
49 49
 
50 50
 bool cpuBreakLoop = false;
... ...
@@ -60,7 +60,7 @@ bool cpuFlashEnabled = true;
60 60
 bool cpuEEPROMEnabled = true;
61 61
 bool cpuEEPROMSensorEnabled = false;
62 62
 
63
-u32 cpuPrefetch[2];
63
+uint32_t cpuPrefetch[2];
64 64
 
65 65
 int cpuTotalTicks = 0;
66 66
 #ifdef PROFILING
... ...
@@ -70,51 +70,51 @@ static profile_segment *profilSegment = NULL;
70 70
 #endif
71 71
 
72 72
 #ifdef BKPT_SUPPORT
73
-u8 freezeWorkRAM[0x40000];
74
-u8 freezeInternalRAM[0x8000];
75
-u8 freezeVRAM[0x18000];
76
-u8 freezePRAM[0x400];
77
-u8 freezeOAM[0x400];
73
+uint8_t freezeWorkRAM[0x40000];
74
+uint8_t freezeInternalRAM[0x8000];
75
+uint8_t freezeVRAM[0x18000];
76
+uint8_t freezePRAM[0x400];
77
+uint8_t freezeOAM[0x400];
78 78
 bool debugger_last;
79 79
 #endif
80 80
 
81 81
 int lcdTicks = (useBios && !skipBios) ? 1008 : 208;
82
-u8 timerOnOffDelay = 0;
83
-u16 timer0Value = 0;
82
+uint8_t timerOnOffDelay = 0;
83
+uint16_t timer0Value = 0;
84 84
 bool timer0On = false;
85 85
 int timer0Ticks = 0;
86 86
 int timer0Reload = 0;
87 87
 int timer0ClockReload  = 0;
88
-u16 timer1Value = 0;
88
+uint16_t timer1Value = 0;
89 89
 bool timer1On = false;
90 90
 int timer1Ticks = 0;
91 91
 int timer1Reload = 0;
92 92
 int timer1ClockReload  = 0;
93
-u16 timer2Value = 0;
93
+uint16_t timer2Value = 0;
94 94
 bool timer2On = false;
95 95
 int timer2Ticks = 0;
96 96
 int timer2Reload = 0;
97 97
 int timer2ClockReload  = 0;
98
-u16 timer3Value = 0;
98
+uint16_t timer3Value = 0;
99 99
 bool timer3On = false;
100 100
 int timer3Ticks = 0;
101 101
 int timer3Reload = 0;
102 102
 int timer3ClockReload  = 0;
103
-u32 dma0Source = 0;
104
-u32 dma0Dest = 0;
105
-u32 dma1Source = 0;
106
-u32 dma1Dest = 0;
107
-u32 dma2Source = 0;
108
-u32 dma2Dest = 0;
109
-u32 dma3Source = 0;
110
-u32 dma3Dest = 0;
103
+uint32_t dma0Source = 0;
104
+uint32_t dma0Dest = 0;
105
+uint32_t dma1Source = 0;
106
+uint32_t dma1Dest = 0;
107
+uint32_t dma2Source = 0;
108
+uint32_t dma2Dest = 0;
109
+uint32_t dma3Source = 0;
110
+uint32_t dma3Dest = 0;
111 111
 //void (*cpuSaveGameFunc)(u32,u8) = /*flashSaveDecide*/0;
112 112
 //void (*renderLine)() = /*mode0RenderLine*/0;
113 113
 bool fxOn = false;
114 114
 bool windowOn = false;
115 115
 int frameCount = 0;
116 116
 char buffer[1024];
117
-u32 lastTime = 0;
117
+uint32_t lastTime = 0;
118 118
 int count = 0;
119 119
 
120 120
 int capture = 0;
... ...
@@ -128,23 +128,23 @@ const int TIMER_TICKS[4] = {
128 128
   10
129 129
 };
130 130
 
131
-const u32  objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
132
-const u8 gamepakRamWaitState[4] = { 4, 3, 2, 8 };
133
-const u8 gamepakWaitState[4] =  { 4, 3, 2, 8 };
134
-const u8 gamepakWaitState0[2] = { 2, 1 };
135
-const u8 gamepakWaitState1[2] = { 4, 1 };
136
-const u8 gamepakWaitState2[2] = { 8, 1 };
131
+const uint32_t  objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
132
+const uint8_t gamepakRamWaitState[4] = { 4, 3, 2, 8 };
133
+const uint8_t gamepakWaitState[4] =  { 4, 3, 2, 8 };
134
+const uint8_t gamepakWaitState0[2] = { 2, 1 };
135
+const uint8_t gamepakWaitState1[2] = { 4, 1 };
136
+const uint8_t gamepakWaitState2[2] = { 8, 1 };
137 137
 const bool isInRom [16]=
138 138
   { false, false, false, false, false, false, false, false,
139 139
     true, true, true, true, true, true, false, false };
140 140
 
141
-u8 memoryWait[16] =
141
+uint8_t memoryWait[16] =
142 142
   { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
143
-u8 memoryWait32[16] =
143
+uint8_t memoryWait32[16] =
144 144
   { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
145
-u8 memoryWaitSeq[16] =
145
+uint8_t memoryWaitSeq[16] =
146 146
   { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
147
-u8 memoryWaitSeq32[16] =
147
+uint8_t memoryWaitSeq32[16] =
148 148
   { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
149 149
 
150 150
 // The videoMemoryWait constants are used to add some waitstates
... ...
@@ -155,13 +155,13 @@ u8 memoryWaitSeq32[16] =
155 155
 //  {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
156 156
 
157 157
 
158
-u8 biosProtected[4];
158
+uint8_t biosProtected[4];
159 159
 
160 160
 #ifdef WORDS_BIGENDIAN
161 161
 bool cpuBiosSwapped = false;
162 162
 #endif
163 163
 
164
-u32 myROM[] = {
164
+uint32_t myROM[] = {
165 165
 0xEA000006,
166 166
 0xEA000093,
167 167
 0xEA000006,
... ...
@@ -546,10 +546,10 @@ inline int CPUUpdateTicks()
546 546
   }
547 547
 }*/
548 548
 
549
-extern u32 line0[240];
550
-extern u32 line1[240];
551
-extern u32 line2[240];
552
-extern u32 line3[240];
549
+/*extern uint32_t line0[240];
550
+extern uint32_t line1[240];
551
+extern uint32_t line2[240];
552
+extern uint32_t line3[240];
553 553
 
554 554
 #define CLEAR_ARRAY(a) \
555 555
   {\
... ...
@@ -557,7 +557,7 @@ extern u32 line3[240];
557 557
     for(int i = 0; i < 240; i++) {\
558 558
       *array++ = 0x80000000;\
559 559
     }\
560
-  }\
560
+  }\*/
561 561
 
562 562
 /*void CPUUpdateRenderBuffers(bool force)
563 563
 {
... ...
@@ -1339,13 +1339,13 @@ int CPULoadRom(const char *szFile)
1339 1339
 
1340 1340
   //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
1341 1341
 
1342
-  rom = (u8 *)malloc(0x2000000);
1342
+  rom = (uint8_t *)malloc(0x2000000);
1343 1343
   if(rom == NULL) {
1344 1344
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1345 1345
                   "ROM");*/
1346 1346
     return 0;
1347 1347
   }
1348
-  workRAM = (u8 *)calloc(1, 0x40000);
1348
+  workRAM = (uint8_t *)calloc(1, 0x40000);
1349 1349
   if(workRAM == NULL) {
1350 1350
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1351 1351
                   "WRAM");*/
... ...
@@ -1395,56 +1395,56 @@ int CPULoadRom(const char *szFile)
1395 1395
 	else
1396 1396
 		mapgsf(rom, 0x2000000,romSize);
1397 1397
 
1398
-  u16 *temp = (u16 *)(rom+((romSize+1)&~1));
1398
+  uint16_t *temp = (uint16_t *)(rom+((romSize+1)&~1));
1399 1399
   int i;
1400 1400
   for(i = (romSize+1)&~1; i < 0x2000000; i+=2) {
1401 1401
     WRITE16LE(temp, (i >> 1) & 0xFFFF);
1402 1402
     temp++;
1403 1403
   }
1404 1404
 
1405
-  bios = (u8 *)calloc(1,0x4000);
1405
+  bios = (uint8_t *)calloc(1,0x4000);
1406 1406
   if(bios == NULL) {
1407 1407
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1408 1408
                   "BIOS");*/
1409 1409
     CPUCleanUp();
1410 1410
     return 0;
1411 1411
   }
1412
-  internalRAM = (u8 *)calloc(1,0x8000);
1412
+  internalRAM = (uint8_t *)calloc(1,0x8000);
1413 1413
   if(internalRAM == NULL) {
1414 1414
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1415 1415
                   "IRAM");*/
1416 1416
     CPUCleanUp();
1417 1417
     return 0;
1418 1418
   }
1419
-  paletteRAM = (u8 *)calloc(1,0x400);
1419
+  paletteRAM = (uint8_t *)calloc(1,0x400);
1420 1420
   if(paletteRAM == NULL) {
1421 1421
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1422 1422
                   "PRAM");*/
1423 1423
     CPUCleanUp();
1424 1424
     return 0;
1425 1425
   }
1426
-  vram = (u8 *)calloc(1, 0x20000);
1426
+  vram = (uint8_t *)calloc(1, 0x20000);
1427 1427
   if(vram == NULL) {
1428 1428
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1429 1429
                   "VRAM");*/
1430 1430
     CPUCleanUp();
1431 1431
     return 0;
1432 1432
   }
1433
-  oam = (u8 *)calloc(1, 0x400);
1433
+  oam = (uint8_t *)calloc(1, 0x400);
1434 1434
   if(oam == NULL) {
1435 1435
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1436 1436
                   "OAM");*/
1437 1437
     CPUCleanUp();
1438 1438
     return 0;
1439 1439
   }
1440
-  pix = (u8 *)calloc(1, 4 * 241 * 162);
1440
+  pix = (uint8_t *)calloc(1, 4 * 241 * 162);
1441 1441
   if(pix == NULL) {
1442 1442
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1443 1443
                   "PIX");*/
1444 1444
     CPUCleanUp();
1445 1445
     return 0;
1446 1446
   }
1447
-  ioMem = (u8 *)calloc(1, 0x400);
1447
+  ioMem = (uint8_t *)calloc(1, 0x400);
1448 1448
   if(ioMem == NULL) {
1449 1449
     /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1450 1450
                   "IO");*/
... ...
@@ -1462,8 +1462,8 @@ int CPULoadRom(const char *szFile)
1462 1462
 
1463 1463
 void doMirroring (bool b)
1464 1464
 {
1465
-  u32 mirroredRomSize = (((romSize)>>20) & 0x3F)<<20;
1466
-  u32 mirroredRomAddress = romSize;
1465
+  uint32_t mirroredRomSize = (((romSize)>>20) & 0x3F)<<20;
1466
+  uint32_t mirroredRomAddress = romSize;
1467 1467
   if ((mirroredRomSize <=0x800000) && (b))
1468 1468
   {
1469 1469
     mirroredRomAddress = mirroredRomSize;
... ...
@@ -1471,7 +1471,7 @@ void doMirroring (bool b)
1471 1471
         mirroredRomSize=0x100000;
1472 1472
     while (mirroredRomAddress<0x01000000)
1473 1473
     {
1474
-      memcpy ((u16 *)(rom+mirroredRomAddress), (u16 *)(rom), mirroredRomSize);
1474
+      memcpy ((uint16_t *)(rom+mirroredRomAddress), (uint16_t *)(rom), mirroredRomSize);
1475 1475
       mirroredRomAddress+=mirroredRomSize;
1476 1476
     }
1477 1477
   }
... ...
@@ -1540,7 +1540,7 @@ void doMirroring (bool b)
1540 1540
 
1541 1541
 void CPUUpdateCPSR()
1542 1542
 {
1543
-  u32 CPSR = reg[16].I & 0x40;
1543
+  uint32_t CPSR = reg[16].I & 0x40;
1544 1544
   if(N_FLAG)
1545 1545
     CPSR |= 0x80000000;
1546 1546
   if(Z_FLAG)
... ...
@@ -1559,7 +1559,7 @@ void CPUUpdateCPSR()
1559 1559
 
1560 1560
 void CPUUpdateFlags(bool breakLoop)
1561 1561
 {
1562
-  u32 CPSR = reg[16].I;
1562
+  uint32_t CPSR = reg[16].I;
1563 1563
 
1564 1564
   N_FLAG = (CPSR & 0x80000000) ? true: false;
1565 1565
   Z_FLAG = (CPSR & 0x40000000) ? true: false;
... ...
@@ -1579,16 +1579,16 @@ void CPUUpdateFlags()
1579 1579
 }
1580 1580
 
1581 1581
 #ifdef WORDS_BIGENDIAN
1582
-static void CPUSwap(volatile u32 *a, volatile u32 *b)
1582
+static void CPUSwap(volatile uint32_t *a, volatile uint32_t *b)
1583 1583
 {
1584
-  volatile u32 c = *b;
1584
+  volatile uint32_t c = *b;
1585 1585
   *b = *a;
1586 1586
   *a = c;
1587 1587
 }
1588 1588
 #else
1589
-static void CPUSwap(u32 *a, u32 *b)
1589
+static void CPUSwap(uint32_t *a, uint32_t *b)
1590 1590
 {
1591
-  u32 c = *b;
1591
+  uint32_t c = *b;
1592 1592
   *b = *a;
1593 1593
   *a = c;
1594 1594
 }
... ...
@@ -1640,8 +1640,8 @@ void CPUSwitchMode(int mode, bool saveState, bool breakLoop)
1640 1640
     break;
1641 1641
   }
1642 1642
 
1643
-  u32 CPSR = reg[16].I;
1644
-  u32 SPSR = reg[17].I;
1643
+  uint32_t CPSR = reg[16].I;
1644
+  uint32_t SPSR = reg[17].I;
1645 1645
 
1646 1646
   switch(mode) {
1647 1647
   case 0x10:
... ...
@@ -1715,7 +1715,7 @@ void CPUSwitchMode(int mode, bool saveState)
1715 1715
 
1716 1716
 void CPUUndefinedException()
1717 1717
 {
1718
-  u32 PC = reg[15].I;
1718
+  uint32_t PC = reg[15].I;
1719 1719
   bool savedArmState = armState;
1720 1720
   CPUSwitchMode(0x1b, true, false);
1721 1721
   reg[14].I = PC - (savedArmState ? 4 : 2);
... ...
@@ -1729,7 +1729,7 @@ void CPUUndefinedException()
1729 1729
 
1730 1730
 void CPUSoftwareInterrupt()
1731 1731
 {
1732
-  u32 PC = reg[15].I;
1732
+  uint32_t PC = reg[15].I;
1733 1733
   bool savedArmState = armState;
1734 1734
   CPUSwitchMode(0x13, true, false);
1735 1735
   reg[14].I = PC - (savedArmState ? 4 : 2);
... ...
@@ -1930,7 +1930,7 @@ void CPUSoftwareInterrupt(int comment)
1930 1930
     break;
1931 1931
   case 0x11:
1932 1932
     {
1933
-      u32 len = CPUReadMemory(reg[0].I) >> 8;
1933
+      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1934 1934
       if(!(((reg[0].I & 0xe000000) == 0) ||
1935 1935
           ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1936 1936
         SWITicks = (9 + memoryWait[(reg[1].I>>24) & 0xF]) * len;
... ...
@@ -1939,7 +1939,7 @@ void CPUSoftwareInterrupt(int comment)
1939 1939
     break;
1940 1940
   case 0x12:
1941 1941
     {
1942
-      u32 len = CPUReadMemory(reg[0].I) >> 8;
1942
+      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1943 1943
       if(!(((reg[0].I & 0xe000000) == 0) ||
1944 1944
           ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1945 1945
         SWITicks = (19 + memoryWait[(reg[1].I>>24) & 0xF]) * len;
... ...
@@ -1948,7 +1948,7 @@ void CPUSoftwareInterrupt(int comment)
1948 1948
     break;
1949 1949
   case 0x13:
1950 1950
     {
1951
-      u32 len = CPUReadMemory(reg[0].I) >> 8;
1951
+      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1952 1952
       if(!(((reg[0].I & 0xe000000) == 0) ||
1953 1953
           ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1954 1954
         SWITicks = (29 + (memoryWait[(reg[0].I>>24) & 0xF]<<1)) * len;
... ...
@@ -1957,7 +1957,7 @@ void CPUSoftwareInterrupt(int comment)
1957 1957
     break;
1958 1958
   case 0x14:
1959 1959
     {
1960
-      u32 len = CPUReadMemory(reg[0].I) >> 8;
1960
+      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1961 1961
       if(!(((reg[0].I & 0xe000000) == 0) ||
1962 1962
           ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1963 1963
         SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] +
... ...
@@ -1967,7 +1967,7 @@ void CPUSoftwareInterrupt(int comment)
1967 1967
     break;
1968 1968
   case 0x15:
1969 1969
     {
1970
-      u32 len = CPUReadMemory(reg[0].I) >> 9;
1970
+      uint32_t len = CPUReadMemory(reg[0].I) >> 9;
1971 1971
       if(!(((reg[0].I & 0xe000000) == 0) ||
1972 1972
           ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1973 1973
         SWITicks = (34 + (memoryWait[(reg[0].I>>24) & 0xF] << 1) +
... ...
@@ -1977,7 +1977,7 @@ void CPUSoftwareInterrupt(int comment)
1977 1977
     break;
1978 1978
   case 0x16:
1979 1979
     {
1980
-      u32 len = CPUReadMemory(reg[0].I) >> 8;
1980
+      uint32_t len = CPUReadMemory(reg[0].I) >> 8;
1981 1981
       if(!(((reg[0].I & 0xe000000) == 0) ||
1982 1982
           ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1983 1983
         SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] +
... ...
@@ -1987,7 +1987,7 @@ void CPUSoftwareInterrupt(int comment)
1987 1987
     break;
1988 1988
   case 0x17:
1989 1989
     {
1990
-      u32 len = CPUReadMemory(reg[0].I) >> 9;
1990
+      uint32_t len = CPUReadMemory(reg[0].I) >> 9;
1991 1991
       if(!(((reg[0].I & 0xe000000) == 0) ||
1992 1992
           ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1993 1993
         SWITicks = (39 + (memoryWait[(reg[0].I>>24) & 0xF]<<1) +
... ...
@@ -1997,7 +1997,7 @@ void CPUSoftwareInterrupt(int comment)
1997 1997
     break;
1998 1998
   case 0x18:
1999 1999
     {
2000
-      u32 len = CPUReadMemory(reg[0].I) >> 9;
2000
+      uint32_t len = CPUReadMemory(reg[0].I) >> 9;
2001 2001
       if(!(((reg[0].I & 0xe000000) == 0) ||
2002 2002
           ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
2003 2003
         SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] +
... ...
@@ -2070,7 +2070,7 @@ void CPUCompareVCOUNT()
2070 2070
 
2071 2071
 }
2072 2072
 
2073
-void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
2073
+void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int transfer32)
2074 2074
 {
2075 2075
   int sm = s >> 24;
2076 2076
   int dm = d >> 24;
... ...
@@ -2154,13 +2154,13 @@ void CPUCheckDMA(int reason, int dmamask)
2154 2154
   // DMA 0
2155 2155
   if((DM0CNT_H & 0x8000) && (dmamask & 1)) {
2156 2156
     if(((DM0CNT_H >> 12) & 3) == reason) {
2157
-      u32 sourceIncrement = 4;
2158
-      u32 destIncrement = 4;
2157
+      uint32_t sourceIncrement = 4;
2158
+      uint32_t destIncrement = 4;
2159 2159
       switch((DM0CNT_H >> 7) & 3) {
2160 2160
       case 0:
2161 2161
         break;
2162 2162
       case 1:
2163
-        sourceIncrement = (u32)-4;
2163
+        sourceIncrement = (uint32_t)-4;
2164 2164
         break;
2165 2165
       case 2:
2166 2166
         sourceIncrement = 0;
... ...
@@ -2170,7 +2170,7 @@ void CPUCheckDMA(int reason, int dmamask)
2170 2170
       case 0:
2171 2171
         break;
2172 2172
       case 1:
2173
-        destIncrement = (u32)-4;
2173
+        destIncrement = (uint32_t)-4;
2174 2174
         break;
2175 2175
       case 2:
2176 2176
         destIncrement = 0;
... ...
@@ -2210,13 +2210,13 @@ void CPUCheckDMA(int reason, int dmamask)
2210 2210
   // DMA 1
2211 2211
   if((DM1CNT_H & 0x8000) && (dmamask & 2)) {
2212 2212
     if(((DM1CNT_H >> 12) & 3) == reason) {
2213
-      u32 sourceIncrement = 4;
2214
-      u32 destIncrement = 4;
2213
+      uint32_t sourceIncrement = 4;
2214
+      uint32_t destIncrement = 4;
2215 2215
       switch((DM1CNT_H >> 7) & 3) {
2216 2216
       case 0:
2217 2217
         break;
2218 2218
       case 1:
2219
-        sourceIncrement = (u32)-4;
2219
+        sourceIncrement = (uint32_t)-4;
2220 2220
         break;
2221 2221
       case 2:
2222 2222
         sourceIncrement = 0;
... ...
@@ -2226,7 +2226,7 @@ void CPUCheckDMA(int reason, int dmamask)
2226 2226
       case 0:
2227 2227
         break;
2228 2228
       case 1:
2229
-        destIncrement = (u32)-4;
2229
+        destIncrement = (uint32_t)-4;
2230 2230
         break;
2231 2231
       case 2:
2232 2232
         destIncrement = 0;
... ...
@@ -2278,13 +2278,13 @@ void CPUCheckDMA(int reason, int dmamask)
2278 2278
   // DMA 2
2279 2279
   if((DM2CNT_H & 0x8000) && (dmamask & 4)) {
2280 2280
     if(((DM2CNT_H >> 12) & 3) == reason) {
2281
-      u32 sourceIncrement = 4;
2282
-      u32 destIncrement = 4;
2281
+      uint32_t sourceIncrement = 4;
2282
+      uint32_t destIncrement = 4;
2283 2283
       switch((DM2CNT_H >> 7) & 3) {
2284 2284
       case 0:
2285 2285
         break;
2286 2286
       case 1:
2287
-        sourceIncrement = (u32)-4;
2287
+        sourceIncrement = (uint32_t)-4;
2288 2288
         break;
2289 2289
       case 2:
2290 2290
         sourceIncrement = 0;
... ...
@@ -2294,7 +2294,7 @@ void CPUCheckDMA(int reason, int dmamask)
2294 2294
       case 0:
2295 2295
         break;
2296 2296
       case 1:
2297
-        destIncrement = (u32)-4;
2297
+        destIncrement = (uint32_t)-4;
2298 2298
         break;
2299 2299
       case 2:
2300 2300
         destIncrement = 0;
... ...
@@ -2347,13 +2347,13 @@ void CPUCheckDMA(int reason, int dmamask)
2347 2347
   // DMA 3
2348 2348
   if((DM3CNT_H & 0x8000) && (dmamask & 8)) {
2349 2349
     if(((DM3CNT_H >> 12) & 3) == reason) {
2350
-      u32 sourceIncrement = 4;
2351
-      u32 destIncrement = 4;
2350
+      uint32_t sourceIncrement = 4;
2351
+      uint32_t destIncrement = 4;
2352 2352
       switch((DM3CNT_H >> 7) & 3) {
2353 2353
       case 0:
2354 2354
         break;
2355 2355
       case 1:
2356
-        sourceIncrement = (u32)-4;
2356
+        sourceIncrement = (uint32_t)-4;
2357 2357
         break;
2358 2358
       case 2:
2359 2359
         sourceIncrement = 0;
... ...
@@ -2363,7 +2363,7 @@ void CPUCheckDMA(int reason, int dmamask)
2363 2363
       case 0:
2364 2364
         break;
2365 2365
       case 1:
2366
-        destIncrement = (u32)-4;
2366
+        destIncrement = (uint32_t)-4;
2367 2367
         break;
2368 2368
       case 2:
2369 2369
         destIncrement = 0;
... ...
@@ -2400,7 +2400,7 @@ void CPUCheckDMA(int reason, int dmamask)
2400 2400
   }
2401 2401
 }
2402 2402
 
2403
-void CPUUpdateRegister(u32 address, u16 value)
2403
+void CPUUpdateRegister(uint32_t address, uint16_t value)
2404 2404
 {
2405 2405
   switch(address)
2406 2406
   {
... ...
@@ -2412,7 +2412,7 @@ void CPUUpdateRegister(u32 address, u16 value)
2412 2412
       }
2413 2413
       bool change = (0 != ((DISPCNT ^ value) & 0x80));
2414 2414
       bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00));
2415
-      u16 changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated
2415
+      uint16_t changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated
2416 2416
 
2417 2417
       DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode
2418 2418
       UPDATE_REG(0x00, DISPCNT);
... ...
@@ -2627,8 +2627,8 @@ void CPUUpdateRegister(u32 address, u16 value)
2627 2627
   case 0x7c:
2628 2628
   case 0x80:
2629 2629
   case 0x84:
2630
-    soundEvent(address&0xFF, (u8)(value & 0xFF));
2631
-    soundEvent((address&0xFF)+1, (u8)(value>>8));
2630
+    soundEvent(address&0xFF, (uint8_t)(value & 0xFF));
2631
+    soundEvent((address&0xFF)+1, (uint8_t)(value>>8));
2632 2632
     break;
2633 2633
   case 0x82:
2634 2634
   case 0x88:
... ...
@@ -3013,8 +3013,8 @@ void applyTimer ()
3013 3013
   timerOnOffDelay = 0;
3014 3014
 }
3015 3015
 
3016
-u8 cpuBitsSet[256];
3017
-u8 cpuLowestBitSet[256];
3016
+uint8_t cpuBitsSet[256];
3017
+uint8_t cpuLowestBitSet[256];
3018 3018
 
3019 3019
 void CPUInit(const char *biosFileName, bool useBiosFile)
3020 3020
 {
... ...
@@ -3105,8 +3105,8 @@ void CPUInit(const char *biosFileName, bool useBiosFile)
3105 3105
     ioReadable[i] = false;
3106 3106
 
3107 3107
   if(romSize < 0x1fe2000) {
3108
-    *((u16 *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA
3109
-    *((u16 *)&rom[0x1fe209e]) = 0x4770; // BX LR
3108
+    *((uint16_t *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA
3109
+    *((uint16_t *)&rom[0x1fe209e]) = 0x4770; // BX LR
3110 3110
   } else {
3111 3111
     //agbPrintEnable(false);
3112 3112
   }
... ...
@@ -3306,7 +3306,7 @@ void CPUReset()
3306 3306
   //CPUUpdateRenderBuffers(true);
3307 3307
 
3308 3308
   for(int i = 0; i < 256; i++) {
3309
-    map[i].address = (u8 *)&dummyAddress;
3309
+    map[i].address = (uint8_t *)&dummyAddress;
3310 3310
     map[i].mask = 0;
3311 3311
   }
3312 3312
 
... ...
@@ -3415,7 +3415,7 @@ void CPUReset()
3415 3415
 
3416 3416
 void CPUInterrupt()
3417 3417
 {
3418
-  u32 PC = reg[15].I;
3418
+  uint32_t PC = reg[15].I;
3419 3419
   bool savedState = armState;
3420 3420
   CPUSwitchMode(0x12, true, false);
3421 3421
   reg[14].I = PC;
... ...
@@ -3547,9 +3547,9 @@ void CPULoop(int ticks)
3547 3547
             CPUCompareVCOUNT();
3548 3548
           }
3549 3549
         } else {
3550
-          int framesToSkip = /*systemFrameSkip*/0;
3550
+          /*int framesToSkip = *//*systemFrameSkip*//*0;
3551 3551
           if(speedup)
3552
-            framesToSkip = 9; // try 6 FPS during speedup
3552
+            framesToSkip = 9;*/ // try 6 FPS during speedup
3553 3553
 
3554 3554
           if(DISPSTAT & 2) {
3555 3555
             // if in H-Blank, leave it and move to drawing mode
... ...
@@ -3562,28 +3562,28 @@ void CPULoop(int ticks)
3562 3562
               count++;
3563 3563
               //systemFrame();
3564 3564
 
3565
-              if((count % 10) == 0) {
3565
+              /*if((count % 10) == 0) {
3566 3566
                 //system10Frames(60);
3567
-              }
3567
+              }*/
3568 3568
               if(count == 60) {
3569
-                u32 time = /*systemGetClock()*/0;
3569
+                /*u32 time = *//*systemGetClock()*//*0;
3570 3570
                 if(time != lastTime) {
3571 3571
                   //u32 t = 100000/(time - lastTime);
3572 3572
                   //systemShowSpeed(t);
3573 3573
                 } else
3574 3574
                   //systemShowSpeed(0);
3575
-                lastTime = time;
3575
+                lastTime = time;*/
3576 3576
                 count = 0;
3577 3577
               }
3578
-              u32 joy = 0;
3578
+              //u32 joy = 0;
3579 3579
               // update joystick information
3580 3580
               /*if(systemReadJoypads())
3581 3581
                 // read default joystick
3582 3582
                 joy = systemReadJoypad(-1);*/
3583
-              P1 = 0x03FF ^ (joy & 0x3FF);
3583
+              //P1 = 0x03FF ^ (joy & 0x3FF);
3584 3584
               /*if(cpuEEPROMSensorEnabled)
3585 3585
                 systemUpdateMotionSensor();*/
3586
-              UPDATE_REG(0x130, P1);
3586
+              /*UPDATE_REG(0x130, P1);
3587 3587
               u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132]));
3588 3588
               // this seems wrong, but there are cases where the game
3589 3589
               // can enter the stop state without requesting an IRQ from
... ...
@@ -3603,18 +3603,18 @@ void CPULoop(int ticks)
3603 3603
                 }
3604 3604
               }
3605 3605
 
3606
-              u32 ext = (joy >> 10);
3606
+              u32 ext = (joy >> 10);*/
3607 3607
               // If no (m) code is enabled, apply the cheats at each LCDline
3608 3608
               /*if((cheatsEnabled) && (mastercode==0))
3609 3609
                 remainingTicks += cheatsCheckKeys(P1^0x3FF, ext);*/
3610
-              speedup = (ext & 1) ? true : false;
3610
+              /*speedup = (ext & 1) ? true : false;
3611 3611
               capture = (ext & 2) ? true : false;
3612 3612
 
3613 3613
               if(capture && !capturePrevious) {
3614 3614
                 captureNumber++;
3615 3615
                 //systemScreenCapture(captureNumber);
3616 3616
               }
3617
-              capturePrevious = capture;
3617
+              capturePrevious = capture;*/
3618 3618
 
3619 3619
               DISPSTAT |= 1;
3620 3620
               DISPSTAT &= 0xFFFD;
... ...
@@ -3624,10 +3624,10 @@ void CPULoop(int ticks)
3624 3624
                 UPDATE_REG(0x202, IF);
3625 3625
               }
3626 3626
               CPUCheckDMA(1, 0x0f);
3627
-              if(frameCount >= framesToSkip) {
3627
+              /*if(frameCount >= framesToSkip) {
3628 3628
                 //systemDrawScreen();
3629 3629
                 frameCount = 0;
3630
-              } else
3630
+              } else*/
3631 3631
                 frameCount++;
3632 3632
               /*if(systemPauseOnFrame())
3633 3633
                 ticks = 0;*/
... ...
@@ -3637,8 +3637,8 @@ void CPULoop(int ticks)
3637 3637
             CPUCompareVCOUNT();
3638 3638
 
3639 3639
           } else {
3640
-            if(frameCount >= framesToSkip)
3641
-            {
3640
+            /*if(frameCount >= framesToSkip)
3641
+            {*/
3642 3642
               /*(*renderLine)();
3643 3643
               switch(systemColorDepth) {
3644 3644
                 case 16:
... ...
@@ -3738,7 +3738,7 @@ void CPULoop(int ticks)
3738 3738
                 }
3739 3739
                 break;
3740 3740
               }*/
3741
-            }
3741
+            /*}*/
3742 3742
             // entering H-Blank
3743 3743
             DISPSTAT |= 2;
3744 3744
             UPDATE_REG(0x04, DISPSTAT);
... ...
@@ -3876,7 +3876,7 @@ void CPULoop(int ticks)
3876 3876
         if(profilSegment) {
3877 3877
 	  profile_segment *seg = profilSegment;
3878 3878
 	  do {
3879
-	    u16 *b = (u16 *)seg->sbuf;
3879
+	    uint16_t *b = (uint16_t *)seg->sbuf;
3880 3880
 	    int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale)/0x10000;
3881 3881
 	    if(pc >= 0 && pc < seg->ssiz) {
3882 3882
             b[pc]++;
Browse code

[GSF] Commented out SWI 3 (STOP), based on the last revision of Caitsith2's Highly Advanced GSF plugin, as he said it's not needed for GSFs and actually causes issues with GBS2GSF conversions that are longer than 5 minutes.

Naram Qashat authored on 2013/05/10 15:13:28
Showing 1 changed files
... ...
@@ -1826,10 +1826,10 @@ void CPUSoftwareInterrupt(int comment)
1826 1826
           VCOUNT);*/
1827 1827
     }
1828 1828
 #endif
1829
-    holdState = true;
1829
+    /*holdState = true;
1830 1830
     holdType = -1;
1831 1831
     stopState = true;
1832
-    cpuNextEvent = cpuTotalTicks;
1832
+    cpuNextEvent = cpuTotalTicks;*/
1833 1833
     break;
1834 1834
   case 0x04:
1835 1835
 #ifdef GBA_LOGGING
Browse code

Removed the save state loading from the 2SF player and updated the VBA-M code to the latest revision.

Naram Qashat authored on 2013/04/12 20:27:27
Showing 1 changed files
... ...
@@ -44,7 +44,6 @@ bool busPrefetchEnable = false;
44 44
 u32 busPrefetchCount = 0;
45 45
 int cpuDmaTicksToUpdate = 0;
46 46
 int cpuDmaCount = 0;
47
-bool cpuDmaHack = false;
48 47
 u32 cpuDmaLast = 0;
49 48
 int dummyAddress = 0;
50 49
 
... ...
@@ -936,7 +935,7 @@ bool CPUReadGSASnapshot(const char *fileName)
936 935
   fseek(file, 0x0, SEEK_SET);
937 936
   fread(&i, 1, 4, file);
938 937
   fseek(file, i, SEEK_CUR); // Skip SharkPortSave
939
-  fseek(file, 4, SEEK_CUR); // skip some sort of flag
938
+//  fseek(file, 4, SEEK_CUR); // skip some sort of flag
940 939
   fread(&i, 1, 4, file); // name length
941 940
   fseek(file, i, SEEK_CUR); // skip name
942 941
   fread(&i, 1, 4, file); // desc length
... ...
@@ -1812,8 +1811,8 @@ void CPUSoftwareInterrupt(int comment)
1812 1811
   case 0x02:
1813 1812
 #ifdef GBA_LOGGING
1814 1813
     if(systemVerbose & VERBOSE_SWI) {
1815
-      log("Halt: (VCOUNT = %2d)\n",
1816
-          VCOUNT);
1814
+      /*log("Halt: (VCOUNT = %2d)\n",
1815
+          VCOUNT);*/
1817 1816
     }
1818 1817
 #endif
1819 1818
     holdState = true;
... ...
@@ -1823,8 +1822,8 @@ void CPUSoftwareInterrupt(int comment)
1823 1822
   case 0x03:
1824 1823
 #ifdef GBA_LOGGING
1825 1824
     if(systemVerbose & VERBOSE_SWI) {
1826
-      log("Stop: (VCOUNT = %2d)\n",
1827
-          VCOUNT);
1825
+      /*log("Stop: (VCOUNT = %2d)\n",
1826
+          VCOUNT);*/
1828 1827
     }
1829 1828
 #endif
1830 1829
     holdState = true;
... ...
@@ -2190,7 +2189,6 @@ void CPUCheckDMA(int reason, int dmamask)
2190 2189
       doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement,
2191 2190
             DM0CNT_L ? DM0CNT_L : 0x4000,
2192 2191
             DM0CNT_H & 0x0400);
2193
-      cpuDmaHack = true;
2194 2192
 
2195 2193
       if(DM0CNT_H & 0x4000) {
2196 2194
         IF |= 0x0100;
... ...
@@ -2259,7 +2257,6 @@ void CPUCheckDMA(int reason, int dmamask)
2259 2257
               DM1CNT_L ? DM1CNT_L : 0x4000,
2260 2258
               DM1CNT_H & 0x0400);
2261 2259
       }
2262
-      cpuDmaHack = true;
2263 2260
 
2264 2261
       if(DM1CNT_H & 0x4000) {
2265 2262
         IF |= 0x0200;
... ...
@@ -2329,7 +2326,6 @@ void CPUCheckDMA(int reason, int dmamask)
2329 2326
               DM2CNT_L ? DM2CNT_L : 0x4000,
2330 2327
               DM2CNT_H & 0x0400);
2331 2328
       }
2332
-      cpuDmaHack = true;
2333 2329
 
2334 2330
       if(DM2CNT_H & 0x4000) {
2335 2331
         IF |= 0x0400;
... ...
@@ -3412,8 +3408,6 @@ void CPUReset()
3412 3408
 
3413 3409
   //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
3414 3410
 
3415
-  cpuDmaHack = false;
3416
-
3417 3411
   lastTime = /*systemGetClock()*/0;
3418 3412
 
3419 3413
   SWITicks = 0;
... ...
@@ -3512,7 +3506,6 @@ void CPULoop(int ticks)
3512 3506
 
3513 3507
       clockTicks = cpuNextEvent;
3514 3508
       cpuTotalTicks = 0;
3515
-      cpuDmaHack = false;
3516 3509
 
3517 3510
     updateLoop:
3518 3511
 
... ...
@@ -3914,7 +3907,6 @@ void CPULoop(int ticks)
3914 3907
         cpuDmaTicksToUpdate -= clockTicks;
3915 3908
         if(cpuDmaTicksToUpdate < 0)
3916 3909
           cpuDmaTicksToUpdate = 0;
3917
-        cpuDmaHack = true;
3918 3910
         goto updateLoop;
3919 3911
       }
3920 3912
 
Browse code

Cleanup of some warnings, updating modification dates, using nullptr instead of NULL in some cases.

Naram Qashat authored on 2013/03/30 16:17:42
Showing 1 changed files
... ...
@@ -1353,7 +1353,7 @@ int CPULoadRom(const char *szFile)
1353 1353
     return 0;
1354 1354
   }
1355 1355
 
1356
-  u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom;
1356
+  //u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom;
1357 1357
 
1358 1358
 #ifndef NO_DEBUGGER
1359 1359
   if(CPUIsELF(szFile)) {
... ...
@@ -3575,7 +3575,7 @@ void CPULoop(int ticks)
3575 3575
               if(count == 60) {
3576 3576
                 u32 time = /*systemGetClock()*/0;
3577 3577
                 if(time != lastTime) {
3578
-                  u32 t = 100000/(time - lastTime);
3578
+                  //u32 t = 100000/(time - lastTime);
3579 3579
                   //systemShowSpeed(t);
3580 3580
                 } else
3581 3581
                   //systemShowSpeed(0);
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,4025 @@
1
+#include <stdio.h>
2
+#include <stdlib.h>
3
+#include <memory.h>
4
+#include <stdarg.h>
5
+#include <string.h>
6
+#include "GBA.h"
7
+#include "GBAcpu.h"
8
+#include "GBAinline.h"
9
+#include "Globals.h"
10
+//#include "GBAGfx.h"
11
+//#include "EEprom.h"
12
+//#include "Flash.h"
13
+#include "Sound.h"
14
+//#include "Sram.h"
15
+#include "bios.h"
16
+//#include "Cheats.h"
17
+//#include "../NLS.h"
18
+//#include "elf.h"
19
+//#include "../Util.h"
20
+#include "../common/Port.h"
21
+//#include "../System.h"
22
+//#include "agbprint.h"
23
+//#include "GBALink.h"
24
+
25
+extern int mapgsf(u8* a, int l, int &s);
26
+
27
+#ifdef PROFILING
28
+#include "prof/prof.h"
29
+#endif
30
+
31
+#ifdef __GNUC__
32
+#define _stricmp strcasecmp
33
+#endif
34
+
35
+extern int emulating;
36
+
37
+int SWITicks = 0;
38
+int IRQTicks = 0;
39
+
40
+u32 mastercode = 0;
41
+int layerEnableDelay = 0;
42
+bool busPrefetch = false;
43
+bool busPrefetchEnable = false;
44
+u32 busPrefetchCount = 0;
45
+int cpuDmaTicksToUpdate = 0;
46
+int cpuDmaCount = 0;
47
+bool cpuDmaHack = false;
48
+u32 cpuDmaLast = 0;
49
+int dummyAddress = 0;
50
+
51
+bool cpuBreakLoop = false;
52
+int cpuNextEvent = 0;
53
+
54
+int gbaSaveType = 0; // used to remember the save type on reset
55
+bool intState = false;
56
+bool stopState = false;
57
+bool holdState = false;
58
+int holdType = 0;
59
+bool cpuSramEnabled = true;
60
+bool cpuFlashEnabled = true;
61
+bool cpuEEPROMEnabled = true;
62
+bool cpuEEPROMSensorEnabled = false;
63
+
64
+u32 cpuPrefetch[2];
65
+
66
+int cpuTotalTicks = 0;
67
+#ifdef PROFILING
68
+int profilingTicks = 0;
69
+int profilingTicksReload = 0;
70
+static profile_segment *profilSegment = NULL;
71
+#endif
72
+
73
+#ifdef BKPT_SUPPORT
74
+u8 freezeWorkRAM[0x40000];
75
+u8 freezeInternalRAM[0x8000];
76
+u8 freezeVRAM[0x18000];
77
+u8 freezePRAM[0x400];
78
+u8 freezeOAM[0x400];
79
+bool debugger_last;
80
+#endif
81
+
82
+int lcdTicks = (useBios && !skipBios) ? 1008 : 208;
83
+u8 timerOnOffDelay = 0;
84
+u16 timer0Value = 0;
85
+bool timer0On = false;
86
+int timer0Ticks = 0;
87
+int timer0Reload = 0;
88
+int timer0ClockReload  = 0;
89
+u16 timer1Value = 0;
90
+bool timer1On = false;
91
+int timer1Ticks = 0;
92
+int timer1Reload = 0;
93
+int timer1ClockReload  = 0;
94
+u16 timer2Value = 0;
95
+bool timer2On = false;
96
+int timer2Ticks = 0;
97
+int timer2Reload = 0;
98
+int timer2ClockReload  = 0;
99
+u16 timer3Value = 0;
100
+bool timer3On = false;
101
+int timer3Ticks = 0;
102
+int timer3Reload = 0;
103
+int timer3ClockReload  = 0;
104
+u32 dma0Source = 0;
105
+u32 dma0Dest = 0;
106
+u32 dma1Source = 0;
107
+u32 dma1Dest = 0;
108
+u32 dma2Source = 0;
109
+u32 dma2Dest = 0;
110
+u32 dma3Source = 0;
111
+u32 dma3Dest = 0;
112
+//void (*cpuSaveGameFunc)(u32,u8) = /*flashSaveDecide*/0;
113
+//void (*renderLine)() = /*mode0RenderLine*/0;
114
+bool fxOn = false;
115
+bool windowOn = false;
116
+int frameCount = 0;
117
+char buffer[1024];
118
+u32 lastTime = 0;
119
+int count = 0;
120
+
121
+int capture = 0;
122
+int capturePrevious = 0;
123
+int captureNumber = 0;
124
+
125
+const int TIMER_TICKS[4] = {
126
+  0,
127
+  6,
128
+  8,
129
+  10
130
+};
131
+
132
+const u32  objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
133
+const u8 gamepakRamWaitState[4] = { 4, 3, 2, 8 };
134
+const u8 gamepakWaitState[4] =  { 4, 3, 2, 8 };
135
+const u8 gamepakWaitState0[2] = { 2, 1 };
136
+const u8 gamepakWaitState1[2] = { 4, 1 };
137
+const u8 gamepakWaitState2[2] = { 8, 1 };
138
+const bool isInRom [16]=
139
+  { false, false, false, false, false, false, false, false,
140
+    true, true, true, true, true, true, false, false };
141
+
142
+u8 memoryWait[16] =
143
+  { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
144
+u8 memoryWait32[16] =
145
+  { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
146
+u8 memoryWaitSeq[16] =
147
+  { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
148
+u8 memoryWaitSeq32[16] =
149
+  { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
150
+
151
+// The videoMemoryWait constants are used to add some waitstates
152
+// if the opcode access video memory data outside of vblank/hblank
153
+// It seems to happen on only one ticks for each pixel.
154
+// Not used for now (too problematic with current code).
155
+//const u8 videoMemoryWait[16] =
156
+//  {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
157
+
158
+
159
+u8 biosProtected[4];
160
+
161
+#ifdef WORDS_BIGENDIAN
162
+bool cpuBiosSwapped = false;
163
+#endif
164
+
165
+u32 myROM[] = {
166
+0xEA000006,
167
+0xEA000093,
168
+0xEA000006,
169
+0x00000000,
170
+0x00000000,
171
+0x00000000,
172
+0xEA000088,
173
+0x00000000,
174
+0xE3A00302,
175
+0xE1A0F000,
176
+0xE92D5800,
177
+0xE55EC002,
178
+0xE28FB03C,
179
+0xE79BC10C,
180
+0xE14FB000,
181
+0xE92D0800,
182
+0xE20BB080,
183
+0xE38BB01F,
184
+0xE129F00B,
185
+0xE92D4004,
186
+0xE1A0E00F,
187
+0xE12FFF1C,
188
+0xE8BD4004,
189
+0xE3A0C0D3,
190
+0xE129F00C,
191
+0xE8BD0800,
192
+0xE169F00B,
193
+0xE8BD5800,
194
+0xE1B0F00E,
195
+0x0000009C,
196
+0x0000009C,
197
+0x0000009C,
198
+0x0000009C,
199
+0x000001F8,
200
+0x000001F0,
201
+0x000000AC,
202
+0x000000A0,
203
+0x000000FC,
204
+0x00000168,
205
+0xE12FFF1E,
206
+0xE1A03000,
207
+0xE1A00001,
208
+0xE1A01003,
209
+0xE2113102,
210
+0x42611000,
211
+0xE033C040,
212
+0x22600000,
213
+0xE1B02001,
214
+0xE15200A0,
215
+0x91A02082,
216
+0x3AFFFFFC,
217
+0xE1500002,
218
+0xE0A33003,
219
+0x20400002,
220
+0xE1320001,
221
+0x11A020A2,
222
+0x1AFFFFF9,
223
+0xE1A01000,
224
+0xE1A00003,
225
+0xE1B0C08C,
226
+0x22600000,
227
+0x42611000,
228
+0xE12FFF1E,
229
+0xE92D0010,
230
+0xE1A0C000,
231
+0xE3A01001,
232
+0xE1500001,
233
+0x81A000A0,
234
+0x81A01081,
235
+0x8AFFFFFB,
236
+0xE1A0000C,
237
+0xE1A04001,
238
+0xE3A03000,
239
+0xE1A02001,
240
+0xE15200A0,
241
+0x91A02082,
242
+0x3AFFFFFC,
243
+0xE1500002,
244
+0xE0A33003,
245
+0x20400002,
246
+0xE1320001,
247
+0x11A020A2,
248
+0x1AFFFFF9,
249
+0xE0811003,
250
+0xE1B010A1,
251
+0xE1510004,
252
+0x3AFFFFEE,
253
+0xE1A00004,
254
+0xE8BD0010,
255
+0xE12FFF1E,
256
+0xE0010090,
257
+0xE1A01741,
258
+0xE2611000,
259
+0xE3A030A9,
260
+0xE0030391,
261
+0xE1A03743,
262
+0xE2833E39,
263
+0xE0030391,
264
+0xE1A03743,
265
+0xE2833C09,
266
+0xE283301C,
267
+0xE0030391,
268
+0xE1A03743,
269
+0xE2833C0F,
270
+0xE28330B6,
271
+0xE0030391,
272
+0xE1A03743,
273
+0xE2833C16,
274
+0xE28330AA,
275
+0xE0030391,
276
+0xE1A03743,
277
+0xE2833A02,
278
+0xE2833081,
279
+0xE0030391,
280
+0xE1A03743,
281
+0xE2833C36,
282
+0xE2833051,
283
+0xE0030391,
284
+0xE1A03743,
285
+0xE2833CA2,
286
+0xE28330F9,
287
+0xE0000093,
288
+0xE1A00840,
289
+0xE12FFF1E,
290
+0xE3A00001,
291
+0xE3A01001,
292
+0xE92D4010,
293
+0xE3A03000,
294
+0xE3A04001,
295
+0xE3500000,
296
+0x1B000004,
297
+0xE5CC3301,
298
+0xEB000002,
299
+0x0AFFFFFC,
300
+0xE8BD4010,
301
+0xE12FFF1E,
302
+0xE3A0C301,
303
+0xE5CC3208,
304
+0xE15C20B8,
305
+0xE0110002,
306
+0x10222000,
307
+0x114C20B8,
308
+0xE5CC4208,
309
+0xE12FFF1E,
310
+0xE92D500F,
311
+0xE3A00301,
312
+0xE1A0E00F,
313
+0xE510F004,
314
+0xE8BD500F,
315
+0xE25EF004,
316
+0xE59FD044,
317
+0xE92D5000,
318
+0xE14FC000,
319
+0xE10FE000,
320
+0xE92D5000,
321
+0xE3A0C302,
322
+0xE5DCE09C,
323
+0xE35E00A5,
324
+0x1A000004,
325
+0x05DCE0B4,
326
+0x021EE080,
327
+0xE28FE004,
328
+0x159FF018,
329
+0x059FF018,
330
+0xE59FD018,
331
+0xE8BD5000,
332
+0xE169F00C,
333
+0xE8BD5000,
334
+0xE25EF004,
335
+0x03007FF0,
336
+0x09FE2000,
337
+0x09FFC000,
338
+0x03007FE0
339
+};
340
+
341
+/*variable_desc saveGameStruct[] = {
342
+  { &DISPCNT  , sizeof(u16) },
343
+  { &DISPSTAT , sizeof(u16) },
344
+  { &VCOUNT   , sizeof(u16) },
345
+  { &BG0CNT   , sizeof(u16) },
346
+  { &BG1CNT   , sizeof(u16) },
347
+  { &BG2CNT   , sizeof(u16) },
348
+  { &BG3CNT   , sizeof(u16) },
349
+  { &BG0HOFS  , sizeof(u16) },
350
+  { &BG0VOFS  , sizeof(u16) },
351
+  { &BG1HOFS  , sizeof(u16) },
352
+  { &BG1VOFS  , sizeof(u16) },
353
+  { &BG2HOFS  , sizeof(u16) },
354
+  { &BG2VOFS  , sizeof(u16) },
355
+  { &BG3HOFS  , sizeof(u16) },
356
+  { &BG3VOFS  , sizeof(u16) },
357
+  { &BG2PA    , sizeof(u16) },
358
+  { &BG2PB    , sizeof(u16) },
359
+  { &BG2PC    , sizeof(u16) },
360
+  { &BG2PD    , sizeof(u16) },
361
+  { &BG2X_L   , sizeof(u16) },
362
+  { &BG2X_H   , sizeof(u16) },
363
+  { &BG2Y_L   , sizeof(u16) },
364
+  { &BG2Y_H   , sizeof(u16) },
365
+  { &BG3PA    , sizeof(u16) },
366
+  { &BG3PB    , sizeof(u16) },
367
+  { &BG3PC    , sizeof(u16) },
368
+  { &BG3PD    , sizeof(u16) },
369
+  { &BG3X_L   , sizeof(u16) },
370
+  { &BG3X_H   , sizeof(u16) },
371
+  { &BG3Y_L   , sizeof(u16) },
372
+  { &BG3Y_H   , sizeof(u16) },
373
+  { &WIN0H    , sizeof(u16) },
374
+  { &WIN1H    , sizeof(u16) },
375
+  { &WIN0V    , sizeof(u16) },
376
+  { &WIN1V    , sizeof(u16) },
377
+  { &WININ    , sizeof(u16) },
378
+  { &WINOUT   , sizeof(u16) },
379
+  { &MOSAIC   , sizeof(u16) },
380
+  { &BLDMOD   , sizeof(u16) },
381
+  { &COLEV    , sizeof(u16) },
382
+  { &COLY     , sizeof(u16) },
383
+  { &DM0SAD_L , sizeof(u16) },
384
+  { &DM0SAD_H , sizeof(u16) },
385
+  { &DM0DAD_L , sizeof(u16) },
386
+  { &DM0DAD_H , sizeof(u16) },
387
+  { &DM0CNT_L , sizeof(u16) },
388
+  { &DM0CNT_H , sizeof(u16) },
389
+  { &DM1SAD_L , sizeof(u16) },
390
+  { &DM1SAD_H , sizeof(u16) },
391
+  { &DM1DAD_L , sizeof(u16) },
392
+  { &DM1DAD_H , sizeof(u16) },
393
+  { &DM1CNT_L , sizeof(u16) },
394
+  { &DM1CNT_H , sizeof(u16) },
395
+  { &DM2SAD_L , sizeof(u16) },
396
+  { &DM2SAD_H , sizeof(u16) },
397
+  { &DM2DAD_L , sizeof(u16) },
398
+  { &DM2DAD_H , sizeof(u16) },
399
+  { &DM2CNT_L , sizeof(u16) },
400
+  { &DM2CNT_H , sizeof(u16) },
401
+  { &DM3SAD_L , sizeof(u16) },
402
+  { &DM3SAD_H , sizeof(u16) },
403
+  { &DM3DAD_L , sizeof(u16) },
404
+  { &DM3DAD_H , sizeof(u16) },
405
+  { &DM3CNT_L , sizeof(u16) },
406
+  { &DM3CNT_H , sizeof(u16) },
407
+  { &TM0D     , sizeof(u16) },
408
+  { &TM0CNT   , sizeof(u16) },
409
+  { &TM1D     , sizeof(u16) },
410
+  { &TM1CNT   , sizeof(u16) },
411
+  { &TM2D     , sizeof(u16) },
412
+  { &TM2CNT   , sizeof(u16) },
413
+  { &TM3D     , sizeof(u16) },
414
+  { &TM3CNT   , sizeof(u16) },
415
+  { &P1       , sizeof(u16) },
416
+  { &IE       , sizeof(u16) },
417
+  { &IF       , sizeof(u16) },
418
+  { &IME      , sizeof(u16) },
419
+  { &holdState, sizeof(bool) },
420
+  { &holdType, sizeof(int) },
421
+  { &lcdTicks, sizeof(int) },
422
+  { &timer0On , sizeof(bool) },
423
+  { &timer0Ticks , sizeof(int) },
424
+  { &timer0Reload , sizeof(int) },
425
+  { &timer0ClockReload  , sizeof(int) },
426
+  { &timer1On , sizeof(bool) },
427
+  { &timer1Ticks , sizeof(int) },
428
+  { &timer1Reload , sizeof(int) },
429
+  { &timer1ClockReload  , sizeof(int) },
430
+  { &timer2On , sizeof(bool) },
431
+  { &timer2Ticks , sizeof(int) },
432
+  { &timer2Reload , sizeof(int) },
433
+  { &timer2ClockReload  , sizeof(int) },
434
+  { &timer3On , sizeof(bool) },
435
+  { &timer3Ticks , sizeof(int) },
436
+  { &timer3Reload , sizeof(int) },
437
+  { &timer3ClockReload  , sizeof(int) },
438
+  { &dma0Source , sizeof(u32) },
439
+  { &dma0Dest , sizeof(u32) },
440
+  { &dma1Source , sizeof(u32) },
441
+  { &dma1Dest , sizeof(u32) },
442
+  { &dma2Source , sizeof(u32) },
443
+  { &dma2Dest , sizeof(u32) },
444
+  { &dma3Source , sizeof(u32) },
445
+  { &dma3Dest , sizeof(u32) },
446
+  { &fxOn, sizeof(bool) },
447
+  { &windowOn, sizeof(bool) },
448
+  { &N_FLAG , sizeof(bool) },
449
+  { &C_FLAG , sizeof(bool) },
450
+  { &Z_FLAG , sizeof(bool) },
451
+  { &V_FLAG , sizeof(bool) },
452
+  { &armState , sizeof(bool) },
453
+  { &armIrqEnable , sizeof(bool) },
454
+  { &armNextPC , sizeof(u32) },
455
+  { &armMode , sizeof(int) },
456
+  { &saveType , sizeof(int) },
457
+  { NULL, 0 }
458
+};*/
459
+
460
+static int romSize = 0x2000000;
461
+
462
+#ifdef PROFILING
463
+void cpuProfil(profile_segment *seg)
464
+{
465
+    profilSegment = seg;
466
+}
467
+
468
+void cpuEnableProfiling(int hz)
469
+{
470
+  if(hz == 0)
471
+    hz = 100;
472
+  profilingTicks = profilingTicksReload = 16777216 / hz;
473
+  profSetHertz(hz);
474
+}
475
+#endif
476
+
477
+
478
+inline int CPUUpdateTicks()
479
+{
480
+  int cpuLoopTicks = lcdTicks;
481
+
482
+  if(soundTicks < cpuLoopTicks)
483
+    cpuLoopTicks = soundTicks;
484
+
485
+  if(timer0On && (timer0Ticks < cpuLoopTicks)) {
486
+    cpuLoopTicks = timer0Ticks;
487
+  }
488
+  if(timer1On && !(TM1CNT & 4) && (timer1Ticks < cpuLoopTicks)) {
489
+    cpuLoopTicks = timer1Ticks;
490
+  }
491
+  if(timer2On && !(TM2CNT & 4) && (timer2Ticks < cpuLoopTicks)) {
492
+    cpuLoopTicks = timer2Ticks;
493
+  }
494
+  if(timer3On && !(TM3CNT & 4) && (timer3Ticks < cpuLoopTicks)) {
495
+    cpuLoopTicks = timer3Ticks;
496
+  }
497
+#ifdef PROFILING
498
+  if(profilingTicksReload != 0) {
499
+    if(profilingTicks < cpuLoopTicks) {
500
+      cpuLoopTicks = profilingTicks;
501
+    }
502
+  }
503
+#endif
504
+
505
+  if (SWITicks) {
506
+    if (SWITicks < cpuLoopTicks)
507
+        cpuLoopTicks = SWITicks;
508
+  }
509
+
510
+  if (IRQTicks) {
511
+    if (IRQTicks < cpuLoopTicks)
512
+        cpuLoopTicks = IRQTicks;
513
+  }
514
+
515
+  return cpuLoopTicks;
516
+}
517
+
518
+/*void CPUUpdateWindow0()
519
+{
520
+  int x00 = WIN0H>>8;
521
+  int x01 = WIN0H & 255;
522
+
523
+  if(x00 <= x01) {
524
+    for(int i = 0; i < 240; i++) {
525
+      gfxInWin0[i] = (i >= x00 && i < x01);
526
+    }
527
+  } else {
528
+    for(int i = 0; i < 240; i++) {
529
+      gfxInWin0[i] = (i >= x00 || i < x01);
530
+    }
531
+  }
532
+}*/
533
+
534
+/*void CPUUpdateWindow1()
535
+{
536
+  int x00 = WIN1H>>8;
537
+  int x01 = WIN1H & 255;
538
+
539
+  if(x00 <= x01) {
540
+    for(int i = 0; i < 240; i++) {
541
+      gfxInWin1[i] = (i >= x00 && i < x01);
542
+    }
543
+  } else {
544
+    for(int i = 0; i < 240; i++) {
545
+      gfxInWin1[i] = (i >= x00 || i < x01);
546
+    }
547
+  }
548
+}*/
549
+
550
+extern u32 line0[240];
551
+extern u32 line1[240];
552
+extern u32 line2[240];
553
+extern u32 line3[240];
554
+
555
+#define CLEAR_ARRAY(a) \
556
+  {\
557
+    u32 *array = (a);\
558
+    for(int i = 0; i < 240; i++) {\
559
+      *array++ = 0x80000000;\
560
+    }\
561
+  }\
562
+
563
+/*void CPUUpdateRenderBuffers(bool force)
564
+{
565
+  if(!(layerEnable & 0x0100) || force) {
566
+    CLEAR_ARRAY(line0);
567
+  }
568
+  if(!(layerEnable & 0x0200) || force) {
569
+    CLEAR_ARRAY(line1);
570
+  }
571
+  if(!(layerEnable & 0x0400) || force) {
572
+    CLEAR_ARRAY(line2);
573
+  }
574
+  if(!(layerEnable & 0x0800) || force) {
575
+    CLEAR_ARRAY(line3);
576
+  }
577
+}*/
578
+
579
+/*static bool CPUWriteState(gzFile gzFile)
580
+{
581
+  utilWriteInt(gzFile, SAVE_GAME_VERSION);
582
+
583
+  utilGzWrite(gzFile, &rom[0xa0], 16);
584
+
585
+  utilWriteInt(gzFile, useBios);
586
+
587
+  utilGzWrite(gzFile, &reg[0], sizeof(reg));
588
+
589
+  utilWriteData(gzFile, saveGameStruct);
590
+
591
+  // new to version 0.7.1
592
+  utilWriteInt(gzFile, stopState);
593
+  // new to version 0.8
594
+  utilWriteInt(gzFile, IRQTicks);
595
+
596
+  utilGzWrite(gzFile, internalRAM, 0x8000);
597
+  utilGzWrite(gzFile, paletteRAM, 0x400);
598
+  utilGzWrite(gzFile, workRAM, 0x40000);
599
+  utilGzWrite(gzFile, vram, 0x20000);
600
+  utilGzWrite(gzFile, oam, 0x400);
601
+  utilGzWrite(gzFile, pix, 4*241*162);
602
+  utilGzWrite(gzFile, ioMem, 0x400);
603
+
604
+  eepromSaveGame(gzFile);
605
+  flashSaveGame(gzFile);
606
+  soundSaveGame(gzFile);
607
+
608
+  cheatsSaveGame(gzFile);
609
+
610
+  // version 1.5
611
+  rtcSaveGame(gzFile);
612
+
613
+  return true;
614
+}
615
+
616
+bool CPUWriteState(const char *file)
617
+{
618
+  gzFile gzFile = utilGzOpen(file, "wb");
619
+
620
+  if(gzFile == NULL) {
621
+    systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), file);
622
+    return false;
623
+  }
624
+
625
+  bool res = CPUWriteState(gzFile);
626
+
627
+  utilGzClose(gzFile);
628
+
629
+  return res;
630
+}
631
+
632
+bool CPUWriteMemState(char *memory, int available)
633
+{
634
+  gzFile gzFile = utilMemGzOpen(memory, available, "w");
635
+
636
+  if(gzFile == NULL) {
637
+    return false;
638
+  }
639
+
640
+  bool res = CPUWriteState(gzFile);
641
+
642
+  long pos = utilGzMemTell(gzFile)+8;
643
+
644
+  if(pos >= (available))
645
+    res = false;
646
+
647
+  utilGzClose(gzFile);
648
+
649
+  return res;
650
+}
651
+
652
+static bool CPUReadState(gzFile gzFile)
653
+{
654
+  int version = utilReadInt(gzFile);
655
+
656
+  if(version > SAVE_GAME_VERSION || version < SAVE_GAME_VERSION_1) {
657
+    systemMessage(MSG_UNSUPPORTED_VBA_SGM,
658
+                  N_("Unsupported VisualBoyAdvance save game version %d"),
659
+                  version);
660
+    return false;
661
+  }
662
+
663
+  u8 romname[17];
664
+
665
+  utilGzRead(gzFile, romname, 16);
666
+
667
+  if(memcmp(&rom[0xa0], romname, 16) != 0) {
668
+    romname[16]=0;
669
+    for(int i = 0; i < 16; i++)
670
+      if(romname[i] < 32)
671
+        romname[i] = 32;
672
+    systemMessage(MSG_CANNOT_LOAD_SGM, N_("Cannot load save game for %s"), romname);
673
+    return false;
674
+  }
675
+
676
+  bool ub = utilReadInt(gzFile) ? true : false;
677
+
678
+  if(ub != useBios) {
679
+    if(useBios)
680
+      systemMessage(MSG_SAVE_GAME_NOT_USING_BIOS,
681
+                    N_("Save game is not using the BIOS files"));
682
+    else
683
+      systemMessage(MSG_SAVE_GAME_USING_BIOS,
684
+                    N_("Save game is using the BIOS file"));
685
+    return false;
686
+  }
687
+
688
+  utilGzRead(gzFile, &reg[0], sizeof(reg));
689
+
690
+  utilReadData(gzFile, saveGameStruct);
691
+
692
+  if(version < SAVE_GAME_VERSION_3)
693
+    stopState = false;
694
+  else
695
+    stopState = utilReadInt(gzFile) ? true : false;
696
+
697
+  if(version < SAVE_GAME_VERSION_4)
698
+  {
699
+    IRQTicks = 0;
700
+    intState = false;
701
+  }
702
+  else
703
+  {
704
+    IRQTicks = utilReadInt(gzFile);
705
+    if (IRQTicks>0)
706
+      intState = true;
707
+    else
708
+    {
709
+      intState = false;
710
+      IRQTicks = 0;
711
+    }
712
+  }
713
+
714
+  utilGzRead(gzFile, internalRAM, 0x8000);
715
+  utilGzRead(gzFile, paletteRAM, 0x400);
716
+  utilGzRead(gzFile, workRAM, 0x40000);
717
+  utilGzRead(gzFile, vram, 0x20000);
718
+  utilGzRead(gzFile, oam, 0x400);
719
+  if(version < SAVE_GAME_VERSION_6)
720
+    utilGzRead(gzFile, pix, 4*240*160);
721
+  else
722
+    utilGzRead(gzFile, pix, 4*241*162);
723
+  utilGzRead(gzFile, ioMem, 0x400);
724
+
725
+  if(skipSaveGameBattery) {
726
+    // skip eeprom data
727
+    eepromReadGameSkip(gzFile, version);
728
+    // skip flash data
729
+    flashReadGameSkip(gzFile, version);
730
+  } else {
731
+    eepromReadGame(gzFile, version);
732
+    flashReadGame(gzFile, version);
733
+  }
734
+  soundReadGame(gzFile, version);
735
+
736
+  if(version > SAVE_GAME_VERSION_1) {
737
+    if(skipSaveGameCheats) {
738
+      // skip cheats list data
739
+      cheatsReadGameSkip(gzFile, version);
740
+    } else {
741
+      cheatsReadGame(gzFile, version);
742
+    }
743
+  }
744
+  if(version > SAVE_GAME_VERSION_6) {
745
+    rtcReadGame(gzFile);
746
+  }
747
+
748
+  if(version <= SAVE_GAME_VERSION_7) {
749
+    u32 temp;
750
+#define SWAP(a,b,c) \
751
+    temp = (a);\
752
+    (a) = (b)<<16|(c);\
753
+    (b) = (temp) >> 16;\
754
+    (c) = (temp) & 0xFFFF;
755
+
756
+    SWAP(dma0Source, DM0SAD_H, DM0SAD_L);
757
+    SWAP(dma0Dest,   DM0DAD_H, DM0DAD_L);
758
+    SWAP(dma1Source, DM1SAD_H, DM1SAD_L);
759
+    SWAP(dma1Dest,   DM1DAD_H, DM1DAD_L);
760
+    SWAP(dma2Source, DM2SAD_H, DM2SAD_L);
761
+    SWAP(dma2Dest,   DM2DAD_H, DM2DAD_L);
762
+    SWAP(dma3Source, DM3SAD_H, DM3SAD_L);
763
+    SWAP(dma3Dest,   DM3DAD_H, DM3DAD_L);
764
+  }
765
+
766
+  if(version <= SAVE_GAME_VERSION_8) {
767
+    timer0ClockReload = TIMER_TICKS[TM0CNT & 3];
768
+    timer1ClockReload = TIMER_TICKS[TM1CNT & 3];
769
+    timer2ClockReload = TIMER_TICKS[TM2CNT & 3];
770
+    timer3ClockReload = TIMER_TICKS[TM3CNT & 3];
771
+
772
+    timer0Ticks = ((0x10000 - TM0D) << timer0ClockReload) - timer0Ticks;
773
+    timer1Ticks = ((0x10000 - TM1D) << timer1ClockReload) - timer1Ticks;
774
+    timer2Ticks = ((0x10000 - TM2D) << timer2ClockReload) - timer2Ticks;
775
+    timer3Ticks = ((0x10000 - TM3D) << timer3ClockReload) - timer3Ticks;
776
+    interp_rate();
777
+  }
778
+
779
+  // set pointers!
780
+  layerEnable = layerSettings & DISPCNT;
781
+
782
+  CPUUpdateRender();
783
+  //CPUUpdateRenderBuffers(true);
784
+  //CPUUpdateWindow0();
785
+  //CPUUpdateWindow1();
786
+  gbaSaveType = 0;
787
+  switch(saveType) {
788
+  case 0:
789
+    cpuSaveGameFunc = flashSaveDecide;
790
+    break;
791
+  case 1:
792
+    cpuSaveGameFunc = sramWrite;
793
+    gbaSaveType = 1;
794
+    break;
795
+  case 2:
796
+    cpuSaveGameFunc = flashWrite;
797
+    gbaSaveType = 2;
798
+    break;
799
+  case 3:
800
+     break;
801
+  case 5:
802
+    gbaSaveType = 5;
803
+    break;
804
+  default:
805
+    systemMessage(MSG_UNSUPPORTED_SAVE_TYPE,
806
+                  N_("Unsupported save type %d"), saveType);
807
+    break;
808
+  }
809
+  if(eepromInUse)
810
+    gbaSaveType = 3;
811
+
812
+  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
813
+  if(armState) {
814
+    ARM_PREFETCH;
815
+  } else {
816
+    THUMB_PREFETCH;
817
+  }
818
+
819
+  CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204));
820
+
821
+  return true;
822
+}
823
+
824
+bool CPUReadMemState(char *memory, int available)
825
+{
826
+  gzFile gzFile = utilMemGzOpen(memory, available, "r");
827
+
828
+  bool res = CPUReadState(gzFile);
829
+
830
+  utilGzClose(gzFile);
831
+
832
+  return res;
833
+}
834
+
835
+bool CPUReadState(const char * file)
836
+{
837
+  gzFile gzFile = utilGzOpen(file, "rb");
838
+
839
+  if(gzFile == NULL)
840
+    return false;
841
+
842
+  bool res = CPUReadState(gzFile);
843
+
844
+  utilGzClose(gzFile);
845
+
846
+  return res;
847
+}
848
+
849
+bool CPUExportEepromFile(const char *fileName)
850
+{
851
+  if(eepromInUse) {
852
+    FILE *file = fopen(fileName, "wb");
853
+
854
+    if(!file) {
855
+      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
856
+                    fileName);
857
+      return false;
858
+    }
859
+
860
+    for(int i = 0; i < eepromSize;) {
861
+      for(int j = 0; j < 8; j++) {
862
+        if(fwrite(&eepromData[i+7-j], 1, 1, file) != 1) {
863
+          fclose(file);
864
+          return false;
865
+        }
866
+      }
867
+      i += 8;
868
+    }
869
+    fclose(file);
870
+  }
871
+  return true;
872
+}
873
+
874
+bool CPUWriteBatteryFile(const char *fileName)
875
+{
876
+  if(gbaSaveType == 0) {
877
+    if(eepromInUse)
878
+      gbaSaveType = 3;
879
+    else switch(saveType) {
880
+    case 1:
881
+      gbaSaveType = 1;
882
+      break;
883
+    case 2:
884
+      gbaSaveType = 2;
885
+      break;
886
+    }
887
+  }
888
+
889
+  if((gbaSaveType) && (gbaSaveType!=5)) {
890
+    FILE *file = fopen(fileName, "wb");
891
+
892
+    if(!file) {
893
+      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
894
+                    fileName);
895
+      return false;
896
+    }
897
+
898
+    // only save if Flash/Sram in use or EEprom in use
899
+    if(gbaSaveType != 3) {
900
+      if(gbaSaveType == 2) {
901
+        if(fwrite(flashSaveMemory, 1, flashSize, file) != (size_t)flashSize) {
902
+          fclose(file);
903
+          return false;
904
+        }
905
+      } else {
906
+        if(fwrite(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
907
+          fclose(file);
908
+          return false;
909
+        }
910
+      }
911
+    } else {
912
+      if(fwrite(eepromData, 1, eepromSize, file) != (size_t)eepromSize) {
913
+        fclose(file);
914
+        return false;
915
+      }
916
+    }
917
+    fclose(file);
918
+  }
919
+  return true;
920
+}
921
+
922
+bool CPUReadGSASnapshot(const char *fileName)
923
+{
924
+  int i;
925
+  FILE *file = fopen(fileName, "rb");
926
+
927
+  if(!file) {
928
+    systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
929
+    return false;
930
+  }
931
+
932
+  // check file size to know what we should read
933
+  fseek(file, 0, SEEK_END);
934
+
935
+  // long size = ftell(file);
936
+  fseek(file, 0x0, SEEK_SET);
937
+  fread(&i, 1, 4, file);
938
+  fseek(file, i, SEEK_CUR); // Skip SharkPortSave
939
+  fseek(file, 4, SEEK_CUR); // skip some sort of flag
940
+  fread(&i, 1, 4, file); // name length
941
+  fseek(file, i, SEEK_CUR); // skip name
942
+  fread(&i, 1, 4, file); // desc length
943
+  fseek(file, i, SEEK_CUR); // skip desc
944
+  fread(&i, 1, 4, file); // notes length
945
+  fseek(file, i, SEEK_CUR); // skip notes
946
+  int saveSize;
947
+  fread(&saveSize, 1, 4, file); // read length
948
+  saveSize -= 0x1c; // remove header size
949
+  char buffer[17];
950
+  char buffer2[17];
951
+  fread(buffer, 1, 16, file);
952
+  buffer[16] = 0;
953
+  for(i = 0; i < 16; i++)
954
+    if(buffer[i] < 32)
955
+      buffer[i] = 32;
956
+  memcpy(buffer2, &rom[0xa0], 16);
957
+  buffer2[16] = 0;
958
+  for(i = 0; i < 16; i++)
959
+    if(buffer2[i] < 32)
960
+      buffer2[i] = 32;
961
+  if(memcmp(buffer, buffer2, 16)) {
962
+    systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
963
+                  N_("Cannot import snapshot for %s. Current game is %s"),
964
+                  buffer,
965
+                  buffer2);
966
+    fclose(file);
967
+    return false;
968
+  }
969
+  fseek(file, 12, SEEK_CUR); // skip some flags
970
+  if(saveSize >= 65536) {
971
+    if(fread(flashSaveMemory, 1, saveSize, file) != (size_t)saveSize) {
972
+      fclose(file);
973
+      return false;
974
+    }
975
+  } else {
976
+    systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE,
977
+                  N_("Unsupported snapshot file %s"),
978
+                  fileName);
979
+    fclose(file);
980
+    return false;
981
+  }
982
+  fclose(file);
983
+  CPUReset();
984
+  return true;
985
+}
986
+
987
+bool CPUReadGSASPSnapshot(const char *fileName)
988
+{
989
+  const char gsvfooter[] = "xV4\x12";
990
+  const size_t namepos=0x0c, namesz=12;
991
+  const size_t footerpos=0x42c, footersz=4;
992
+
993
+  char footer[footersz+1], romname[namesz+1], savename[namesz+1];;
994
+  FILE *file = fopen(fileName, "rb");
995
+
996
+  if(!file) {
997
+    systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
998
+    return false;
999
+  }
1000
+
1001
+  // read save name
1002
+  fseek(file, namepos, SEEK_SET);
1003
+  fread(savename, 1, namesz, file);
1004
+  savename[namesz] = 0;
1005
+
1006
+  memcpy(romname, &rom[0xa0], namesz);
1007
+  romname[namesz] = 0;
1008
+
1009
+  if(memcmp(romname, savename, namesz)) {
1010
+    systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
1011
+                  N_("Cannot import snapshot for %s. Current game is %s"),
1012
+                  savename,
1013
+                  romname);
1014
+    fclose(file);
1015
+    return false;
1016
+  }
1017
+
1018
+  // read footer tag
1019
+  fseek(file, footerpos, SEEK_SET);
1020
+  fread(footer, 1, footersz, file);
1021
+  footer[footersz] = 0;
1022
+
1023
+  if(memcmp(footer, gsvfooter, footersz)) {
1024
+    systemMessage(0,
1025
+                  N_("Unsupported snapshot file %s. Footer '%s' at %u should be '%s'"),
1026
+                  fileName,
1027
+				  footer,
1028
+                  footerpos,
1029
+				  gsvfooter);
1030
+    fclose(file);
1031
+    return false;
1032
+  }
1033
+
1034
+  // Read up to 128k save
1035
+  fread(flashSaveMemory, 1, FLASH_128K_SZ, file);
1036
+
1037
+  fclose(file);
1038
+  CPUReset();
1039
+  return true;
1040
+}
1041
+
1042
+
1043
+bool CPUWriteGSASnapshot(const char *fileName,
1044
+                         const char *title,
1045
+                         const char *desc,
1046
+                         const char *notes)
1047
+{
1048
+  FILE *file = fopen(fileName, "wb");
1049
+
1050
+  if(!file) {
1051
+    systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
1052
+    return false;
1053
+  }
1054
+
1055
+  u8 buffer[17];
1056
+
1057
+  utilPutDword(buffer, 0x0d); // SharkPortSave length
1058
+  fwrite(buffer, 1, 4, file);
1059
+  fwrite("SharkPortSave", 1, 0x0d, file);
1060
+  utilPutDword(buffer, 0x000f0000);
1061
+  fwrite(buffer, 1, 4, file); // save type 0x000f0000 = GBA save
1062
+  utilPutDword(buffer, (u32)strlen(title));
1063
+  fwrite(buffer, 1, 4, file); // title length
1064
+  fwrite(title, 1, strlen(title), file);
1065
+  utilPutDword(buffer, (u32)strlen(desc));
1066
+  fwrite(buffer, 1, 4, file); // desc length
1067
+  fwrite(desc, 1, strlen(desc), file);
1068
+  utilPutDword(buffer, (u32)strlen(notes));
1069
+  fwrite(buffer, 1, 4, file); // notes length
1070
+  fwrite(notes, 1, strlen(notes), file);
1071
+  int saveSize = 0x10000;
1072
+  if(gbaSaveType == 2)
1073
+    saveSize = flashSize;
1074
+  int totalSize = saveSize + 0x1c;
1075
+
1076
+  utilPutDword(buffer, totalSize); // length of remainder of save - CRC
1077
+  fwrite(buffer, 1, 4, file);
1078
+
1079
+  char *temp = new char[0x2001c];
1080
+  memset(temp, 0, 28);
1081
+  memcpy(temp, &rom[0xa0], 16); // copy internal name
1082
+  temp[0x10] = rom[0xbe]; // reserved area (old checksum)
1083
+  temp[0x11] = rom[0xbf]; // reserved area (old checksum)
1084
+  temp[0x12] = rom[0xbd]; // complement check
1085
+  temp[0x13] = rom[0xb0]; // maker
1086
+  temp[0x14] = 1; // 1 save ?
1087
+  memcpy(&temp[0x1c], flashSaveMemory, saveSize); // copy save
1088
+  fwrite(temp, 1, totalSize, file); // write save + header
1089
+  u32 crc = 0;
1090
+
1091
+  for(int i = 0; i < totalSize; i++) {
1092
+    crc += ((u32)temp[i] << (crc % 0x18));
1093
+  }
1094
+
1095
+  utilPutDword(buffer, crc);
1096
+  fwrite(buffer, 1, 4, file); // CRC?
1097
+
1098
+  fclose(file);
1099
+  delete [] temp;
1100
+  return true;
1101
+}
1102
+
1103
+bool CPUImportEepromFile(const char *fileName)
1104
+{
1105
+  FILE *file = fopen(fileName, "rb");
1106
+
1107
+  if(!file)
1108
+    return false;
1109
+
1110
+  // check file size to know what we should read
1111
+  fseek(file, 0, SEEK_END);
1112
+
1113
+  long size = ftell(file);
1114
+  fseek(file, 0, SEEK_SET);
1115
+  if(size == 512 || size == 0x2000) {
1116
+    if(fread(eepromData, 1, size, file) != (size_t)size) {
1117
+      fclose(file);
1118
+      return false;
1119
+    }
1120
+    for(int i = 0; i < size;) {
1121
+      u8 tmp = eepromData[i];
1122
+      eepromData[i] = eepromData[7-i];
1123
+      eepromData[7-i] = tmp;
1124
+      i++;
1125
+      tmp = eepromData[i];
1126
+      eepromData[i] = eepromData[7-i];
1127
+      eepromData[7-i] = tmp;
1128
+      i++;
1129
+      tmp = eepromData[i];
1130
+      eepromData[i] = eepromData[7-i];
1131
+      eepromData[7-i] = tmp;
1132
+      i++;
1133
+      tmp = eepromData[i];
1134
+      eepromData[i] = eepromData[7-i];
1135
+      eepromData[7-i] = tmp;
1136
+      i++;
1137
+      i += 4;
1138
+    }
1139
+  } else {
1140
+    fclose(file);
1141
+    return false;
1142
+  }
1143
+  fclose(file);
1144
+  return true;
1145
+}
1146
+
1147
+bool CPUReadBatteryFile(const char *fileName)
1148
+{
1149
+  FILE *file = fopen(fileName, "rb");
1150
+
1151
+  if(!file)
1152
+    return false;
1153
+
1154
+  // check file size to know what we should read
1155
+  fseek(file, 0, SEEK_END);
1156
+
1157
+  long size = ftell(file);
1158
+  fseek(file, 0, SEEK_SET);
1159
+  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
1160
+
1161
+  if(size == 512 || size == 0x2000) {
1162
+    if(fread(eepromData, 1, size, file) != (size_t)size) {
1163
+      fclose(file);
1164
+      return false;
1165
+    }
1166
+  } else {
1167
+    if(size == 0x20000) {
1168
+      if(fread(flashSaveMemory, 1, 0x20000, file) != 0x20000) {
1169
+        fclose(file);
1170
+        return false;
1171
+      }
1172
+      flashSetSize(0x20000);
1173
+    } else {
1174
+      if(fread(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
1175
+        fclose(file);
1176
+        return false;
1177
+      }
1178
+      flashSetSize(0x10000);
1179
+    }
1180
+  }
1181
+  fclose(file);
1182
+  return true;
1183
+}
1184
+
1185
+bool CPUWritePNGFile(const char *fileName)
1186
+{
1187
+  return utilWritePNGFile(fileName, 240, 160, pix);
1188
+}
1189
+
1190
+bool CPUWriteBMPFile(const char *fileName)
1191
+{
1192
+  return utilWriteBMPFile(fileName, 240, 160, pix);
1193
+}*/
1194
+
1195
+bool CPUIsZipFile(const char * file)
1196
+{
1197
+  if(strlen(file) > 4) {
1198
+    const char * p = strrchr(file,'.');
1199
+
1200
+    if(p != NULL) {
1201
+      if(_stricmp(p, ".zip") == 0)
1202
+        return true;
1203
+    }
1204
+  }
1205
+
1206
+  return false;
1207
+}
1208
+
1209
+bool CPUIsGBAImage(const char * file)
1210
+{
1211
+  cpuIsMultiBoot = false;
1212
+  if(strlen(file) > 4) {
1213
+    const char * p = strrchr(file,'.');
1214
+
1215
+    if(p != NULL) {
1216
+      if(_stricmp(p, ".gba") == 0)
1217
+        return true;
1218
+      if(_stricmp(p, ".agb") == 0)
1219
+        return true;
1220
+      if(_stricmp(p, ".bin") == 0)
1221
+        return true;
1222
+      if(_stricmp(p, ".elf") == 0)
1223
+        return true;
1224
+      if(_stricmp(p, ".mb") == 0) {
1225
+        cpuIsMultiBoot = true;
1226
+        return true;
1227
+      }
1228
+    }
1229
+  }
1230
+
1231
+  return false;
1232
+}
1233
+
1234
+bool CPUIsGBABios(const char * file)
1235
+{
1236
+  if(strlen(file) > 4) {
1237
+    const char * p = strrchr(file,'.');
1238
+
1239
+    if(p != NULL) {
1240
+      if(_stricmp(p, ".gba") == 0)
1241
+        return true;
1242
+      if(_stricmp(p, ".agb") == 0)
1243
+        return true;
1244
+      if(_stricmp(p, ".bin") == 0)
1245
+        return true;
1246
+      if(_stricmp(p, ".bios") == 0)
1247
+        return true;
1248
+      if(_stricmp(p, ".rom") == 0)
1249
+        return true;
1250
+    }
1251
+  }
1252
+
1253
+  return false;
1254
+}
1255
+
1256
+bool CPUIsELF(const char *file)
1257
+{
1258
+  if(file == NULL)
1259
+	  return false;
1260
+
1261
+  if(strlen(file) > 4) {
1262
+    const char * p = strrchr(file,'.');
1263
+
1264
+    if(p != NULL) {
1265
+      if(_stricmp(p, ".elf") == 0)
1266
+        return true;
1267
+    }
1268
+  }
1269
+  return false;
1270
+}
1271
+
1272
+void CPUCleanUp()
1273
+{
1274
+#ifdef PROFILING
1275
+  if(profilingTicksReload) {
1276
+    profCleanup();
1277
+  }
1278
+#endif
1279
+
1280
+  if(rom != NULL) {
1281
+    free(rom);
1282
+    rom = NULL;
1283
+  }
1284
+
1285
+  if(vram != NULL) {
1286
+    free(vram);
1287
+    vram = NULL;
1288
+  }
1289
+
1290
+  if(paletteRAM != NULL) {
1291
+    free(paletteRAM);
1292
+    paletteRAM = NULL;
1293
+  }
1294
+
1295
+  if(internalRAM != NULL) {
1296
+    free(internalRAM);
1297
+    internalRAM = NULL;
1298
+  }
1299
+
1300
+  if(workRAM != NULL) {
1301
+    free(workRAM);
1302
+    workRAM = NULL;
1303
+  }
1304
+
1305
+  if(bios != NULL) {
1306
+    free(bios);
1307
+    bios = NULL;
1308
+  }
1309
+
1310
+  if(pix != NULL) {
1311
+    free(pix);
1312
+    pix = NULL;
1313
+  }
1314
+
1315
+  if(oam != NULL) {
1316
+    free(oam);
1317
+    oam = NULL;
1318
+  }
1319
+
1320
+  if(ioMem != NULL) {
1321
+    free(ioMem);
1322
+    ioMem = NULL;
1323
+  }
1324
+
1325
+#ifndef NO_DEBUGGER
1326
+  elfCleanUp();
1327
+#endif //NO_DEBUGGER
1328
+
1329
+  //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
1330
+
1331
+  //emulating = 0;
1332
+}
1333
+
1334
+int CPULoadRom(const char *szFile)
1335
+{
1336
+  romSize = 0x2000000;
1337
+  if(rom != NULL) {
1338
+    CPUCleanUp();
1339
+  }
1340
+
1341
+  //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
1342
+
1343
+  rom = (u8 *)malloc(0x2000000);
1344
+  if(rom == NULL) {
1345
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1346
+                  "ROM");*/
1347
+    return 0;
1348
+  }
1349
+  workRAM = (u8 *)calloc(1, 0x40000);
1350
+  if(workRAM == NULL) {
1351
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1352
+                  "WRAM");*/
1353
+    return 0;
1354
+  }
1355
+
1356
+  u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom;
1357
+
1358
+#ifndef NO_DEBUGGER
1359
+  if(CPUIsELF(szFile)) {
1360
+    FILE *f = fopen(szFile, "rb");
1361
+    if(!f) {
1362
+      systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"),
1363
+                    szFile);
1364
+      free(rom);
1365
+      rom = NULL;
1366
+      free(workRAM);
1367
+      workRAM = NULL;
1368
+      return 0;
1369
+    }
1370
+    bool res = elfRead(szFile, romSize, f);
1371
+    if(!res || romSize == 0) {
1372
+      free(rom);
1373
+      rom = NULL;
1374
+      free(workRAM);
1375
+      workRAM = NULL;
1376
+      elfCleanUp();
1377
+      return 0;
1378
+    }
1379
+  } else
1380
+#endif //NO_DEBUGGER
1381
+  /*if(szFile!=NULL)
1382
+  {
1383
+	  if(!utilLoad(szFile,
1384
+						  utilIsGBAImage,
1385
+						  whereToLoad,
1386
+						  romSize)) {
1387
+		free(rom);
1388
+		rom = NULL;
1389
+		free(workRAM);
1390
+		workRAM = NULL;
1391
+		return 0;
1392
+	  }
1393
+  }*/
1394
+	if (cpuIsMultiBoot)
1395
+		mapgsf(workRAM,0x40000,romSize);
1396
+	else
1397
+		mapgsf(rom, 0x2000000,romSize);
1398
+
1399
+  u16 *temp = (u16 *)(rom+((romSize+1)&~1));
1400
+  int i;
1401
+  for(i = (romSize+1)&~1; i < 0x2000000; i+=2) {
1402
+    WRITE16LE(temp, (i >> 1) & 0xFFFF);
1403
+    temp++;
1404
+  }
1405
+
1406
+  bios = (u8 *)calloc(1,0x4000);
1407
+  if(bios == NULL) {
1408
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1409
+                  "BIOS");*/
1410
+    CPUCleanUp();
1411
+    return 0;
1412
+  }
1413
+  internalRAM = (u8 *)calloc(1,0x8000);
1414
+  if(internalRAM == NULL) {
1415
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1416
+                  "IRAM");*/
1417
+    CPUCleanUp();
1418
+    return 0;
1419
+  }
1420
+  paletteRAM = (u8 *)calloc(1,0x400);
1421
+  if(paletteRAM == NULL) {
1422
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1423
+                  "PRAM");*/
1424
+    CPUCleanUp();
1425
+    return 0;
1426
+  }
1427
+  vram = (u8 *)calloc(1, 0x20000);
1428
+  if(vram == NULL) {
1429
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1430
+                  "VRAM");*/
1431
+    CPUCleanUp();
1432
+    return 0;
1433
+  }
1434
+  oam = (u8 *)calloc(1, 0x400);
1435
+  if(oam == NULL) {
1436
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1437
+                  "OAM");*/
1438
+    CPUCleanUp();
1439
+    return 0;
1440
+  }
1441
+  pix = (u8 *)calloc(1, 4 * 241 * 162);
1442
+  if(pix == NULL) {
1443
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1444
+                  "PIX");*/
1445
+    CPUCleanUp();
1446
+    return 0;
1447
+  }
1448
+  ioMem = (u8 *)calloc(1, 0x400);
1449
+  if(ioMem == NULL) {
1450
+    /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
1451
+                  "IO");*/
1452
+    CPUCleanUp();
1453
+    return 0;
1454
+  }
1455
+
1456
+  //flashInit();
1457
+  //eepromInit();
1458
+
1459
+  //CPUUpdateRenderBuffers(true);
1460
+
1461
+  return romSize;
1462
+}
1463
+
1464
+void doMirroring (bool b)
1465
+{
1466
+  u32 mirroredRomSize = (((romSize)>>20) & 0x3F)<<20;
1467
+  u32 mirroredRomAddress = romSize;
1468
+  if ((mirroredRomSize <=0x800000) && (b))
1469
+  {
1470
+    mirroredRomAddress = mirroredRomSize;
1471
+    if (mirroredRomSize==0)
1472
+        mirroredRomSize=0x100000;
1473
+    while (mirroredRomAddress<0x01000000)
1474
+    {
1475
+      memcpy ((u16 *)(rom+mirroredRomAddress), (u16 *)(rom), mirroredRomSize);
1476
+      mirroredRomAddress+=mirroredRomSize;
1477
+    }
1478
+  }
1479
+}
1480
+
1481
+/*void CPUUpdateRender()
1482
+{
1483
+  switch(DISPCNT & 7) {
1484
+  case 0:
1485
+    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1486
+       cpuDisableSfx)
1487
+      renderLine = mode0RenderLine;
1488
+    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1489
+      renderLine = mode0RenderLineNoWindow;
1490
+    else
1491
+      renderLine = mode0RenderLineAll;
1492
+    break;
1493
+  case 1:
1494
+    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1495
+       cpuDisableSfx)
1496
+      renderLine = mode1RenderLine;
1497
+    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1498
+      renderLine = mode1RenderLineNoWindow;
1499
+    else
1500
+      renderLine = mode1RenderLineAll;
1501
+    break;
1502
+  case 2:
1503
+    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1504
+       cpuDisableSfx)
1505
+      renderLine = mode2RenderLine;
1506
+    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1507
+      renderLine = mode2RenderLineNoWindow;
1508
+    else
1509
+      renderLine = mode2RenderLineAll;
1510
+    break;
1511
+  case 3:
1512
+    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1513
+       cpuDisableSfx)
1514
+      renderLine = mode3RenderLine;
1515
+    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1516
+      renderLine = mode3RenderLineNoWindow;
1517
+    else
1518
+      renderLine = mode3RenderLineAll;
1519
+    break;
1520
+  case 4:
1521
+    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1522
+       cpuDisableSfx)
1523
+      renderLine = mode4RenderLine;
1524
+    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1525
+      renderLine = mode4RenderLineNoWindow;
1526
+    else
1527
+      renderLine = mode4RenderLineAll;
1528
+    break;
1529
+  case 5:
1530
+    if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
1531
+       cpuDisableSfx)
1532
+      renderLine = mode5RenderLine;
1533
+    else if(fxOn && !windowOn && !(layerEnable & 0x8000))
1534
+      renderLine = mode5RenderLineNoWindow;
1535
+    else
1536
+      renderLine = mode5RenderLineAll;
1537
+  default:
1538
+    break;
1539
+  }
1540
+}*/
1541
+
1542
+void CPUUpdateCPSR()
1543
+{
1544
+  u32 CPSR = reg[16].I & 0x40;
1545
+  if(N_FLAG)
1546
+    CPSR |= 0x80000000;
1547
+  if(Z_FLAG)
1548
+    CPSR |= 0x40000000;
1549
+  if(C_FLAG)
1550
+    CPSR |= 0x20000000;
1551
+  if(V_FLAG)
1552
+    CPSR |= 0x10000000;
1553
+  if(!armState)
1554
+    CPSR |= 0x00000020;
1555
+  if(!armIrqEnable)
1556
+    CPSR |= 0x80;
1557
+  CPSR |= (armMode & 0x1F);
1558
+  reg[16].I = CPSR;
1559
+}
1560
+
1561
+void CPUUpdateFlags(bool breakLoop)
1562
+{
1563
+  u32 CPSR = reg[16].I;
1564
+
1565
+  N_FLAG = (CPSR & 0x80000000) ? true: false;
1566
+  Z_FLAG = (CPSR & 0x40000000) ? true: false;
1567
+  C_FLAG = (CPSR & 0x20000000) ? true: false;
1568
+  V_FLAG = (CPSR & 0x10000000) ? true: false;
1569
+  armState = (CPSR & 0x20) ? false : true;
1570
+  armIrqEnable = (CPSR & 0x80) ? false : true;
1571
+  if(breakLoop) {
1572
+      if (armIrqEnable && (IF & IE) && (IME & 1))
1573
+        cpuNextEvent = cpuTotalTicks;
1574
+  }
1575
+}
1576
+
1577
+void CPUUpdateFlags()
1578
+{
1579
+  CPUUpdateFlags(true);
1580
+}
1581
+
1582
+#ifdef WORDS_BIGENDIAN
1583
+static void CPUSwap(volatile u32 *a, volatile u32 *b)
1584
+{
1585
+  volatile u32 c = *b;
1586
+  *b = *a;
1587
+  *a = c;
1588
+}
1589
+#else
1590
+static void CPUSwap(u32 *a, u32 *b)
1591
+{
1592
+  u32 c = *b;
1593
+  *b = *a;
1594
+  *a = c;
1595
+}
1596
+#endif
1597
+
1598
+void CPUSwitchMode(int mode, bool saveState, bool breakLoop)
1599
+{
1600
+  //  if(armMode == mode)
1601
+  //    return;
1602
+
1603
+  CPUUpdateCPSR();
1604
+
1605
+  switch(armMode) {
1606
+  case 0x10:
1607
+  case 0x1F:
1608
+    reg[R13_USR].I = reg[13].I;
1609
+    reg[R14_USR].I = reg[14].I;
1610
+    reg[17].I = reg[16].I;
1611
+    break;
1612
+  case 0x11:
1613
+    CPUSwap(&reg[R8_FIQ].I, &reg[8].I);
1614
+    CPUSwap(&reg[R9_FIQ].I, &reg[9].I);
1615
+    CPUSwap(&reg[R10_FIQ].I, &reg[10].I);
1616
+    CPUSwap(&reg[R11_FIQ].I, &reg[11].I);
1617
+    CPUSwap(&reg[R12_FIQ].I, &reg[12].I);
1618
+    reg[R13_FIQ].I = reg[13].I;
1619
+    reg[R14_FIQ].I = reg[14].I;
1620
+    reg[SPSR_FIQ].I = reg[17].I;
1621
+    break;
1622
+  case 0x12:
1623
+    reg[R13_IRQ].I  = reg[13].I;
1624
+    reg[R14_IRQ].I  = reg[14].I;
1625
+    reg[SPSR_IRQ].I =  reg[17].I;
1626
+    break;
1627
+  case 0x13:
1628
+    reg[R13_SVC].I  = reg[13].I;
1629
+    reg[R14_SVC].I  = reg[14].I;
1630
+    reg[SPSR_SVC].I =  reg[17].I;
1631
+    break;
1632
+  case 0x17:
1633
+    reg[R13_ABT].I  = reg[13].I;
1634
+    reg[R14_ABT].I  = reg[14].I;
1635
+    reg[SPSR_ABT].I =  reg[17].I;
1636
+    break;
1637
+  case 0x1b:
1638
+    reg[R13_UND].I  = reg[13].I;
1639
+    reg[R14_UND].I  = reg[14].I;
1640
+    reg[SPSR_UND].I =  reg[17].I;
1641
+    break;
1642
+  }
1643
+
1644
+  u32 CPSR = reg[16].I;
1645
+  u32 SPSR = reg[17].I;
1646
+
1647
+  switch(mode) {
1648
+  case 0x10:
1649
+  case 0x1F:
1650
+    reg[13].I = reg[R13_USR].I;
1651
+    reg[14].I = reg[R14_USR].I;
1652
+    reg[16].I = SPSR;
1653
+    break;
1654
+  case 0x11:
1655
+    CPUSwap(&reg[8].I, &reg[R8_FIQ].I);
1656
+    CPUSwap(&reg[9].I, &reg[R9_FIQ].I);
1657
+    CPUSwap(&reg[10].I, &reg[R10_FIQ].I);
1658
+    CPUSwap(&reg[11].I, &reg[R11_FIQ].I);
1659
+    CPUSwap(&reg[12].I, &reg[R12_FIQ].I);
1660
+    reg[13].I = reg[R13_FIQ].I;
1661
+    reg[14].I = reg[R14_FIQ].I;
1662
+    if(saveState)
1663
+      reg[17].I = CPSR;
1664
+    else
1665
+      reg[17].I = reg[SPSR_FIQ].I;
1666
+    break;
1667
+  case 0x12:
1668
+    reg[13].I = reg[R13_IRQ].I;
1669
+    reg[14].I = reg[R14_IRQ].I;
1670
+    reg[16].I = SPSR;
1671
+    if(saveState)
1672
+      reg[17].I = CPSR;
1673
+    else
1674
+      reg[17].I = reg[SPSR_IRQ].I;
1675
+    break;
1676
+  case 0x13:
1677
+    reg[13].I = reg[R13_SVC].I;
1678
+    reg[14].I = reg[R14_SVC].I;
1679
+    reg[16].I = SPSR;
1680
+    if(saveState)
1681
+      reg[17].I = CPSR;
1682
+    else
1683
+      reg[17].I = reg[SPSR_SVC].I;
1684
+    break;
1685
+  case 0x17:
1686
+    reg[13].I = reg[R13_ABT].I;
1687
+    reg[14].I = reg[R14_ABT].I;
1688
+    reg[16].I = SPSR;
1689
+    if(saveState)
1690
+      reg[17].I = CPSR;
1691
+    else
1692
+      reg[17].I = reg[SPSR_ABT].I;
1693
+    break;
1694
+  case 0x1b:
1695
+    reg[13].I = reg[R13_UND].I;
1696
+    reg[14].I = reg[R14_UND].I;
1697
+    reg[16].I = SPSR;
1698
+    if(saveState)
1699
+      reg[17].I = CPSR;
1700
+    else
1701
+      reg[17].I = reg[SPSR_UND].I;
1702
+    break;
1703
+  default:
1704
+    //systemMessage(MSG_UNSUPPORTED_ARM_MODE, N_("Unsupported ARM mode %02x"), mode);
1705
+    break;
1706
+  }
1707
+  armMode = mode;
1708
+  CPUUpdateFlags(breakLoop);
1709
+  CPUUpdateCPSR();
1710
+}
1711
+
1712
+void CPUSwitchMode(int mode, bool saveState)
1713
+{
1714
+  CPUSwitchMode(mode, saveState, true);
1715
+}
1716
+
1717
+void CPUUndefinedException()
1718
+{
1719
+  u32 PC = reg[15].I;
1720
+  bool savedArmState = armState;
1721
+  CPUSwitchMode(0x1b, true, false);
1722
+  reg[14].I = PC - (savedArmState ? 4 : 2);
1723
+  reg[15].I = 0x04;
1724
+  armState = true;
1725
+  armIrqEnable = false;
1726
+  armNextPC = 0x04;
1727
+  ARM_PREFETCH;
1728
+  reg[15].I += 4;
1729
+}
1730
+
1731
+void CPUSoftwareInterrupt()
1732
+{
1733
+  u32 PC = reg[15].I;
1734
+  bool savedArmState = armState;
1735
+  CPUSwitchMode(0x13, true, false);
1736
+  reg[14].I = PC - (savedArmState ? 4 : 2);
1737
+  reg[15].I = 0x08;
1738
+  armState = true;
1739
+  armIrqEnable = false;
1740
+  armNextPC = 0x08;
1741
+  ARM_PREFETCH;
1742
+  reg[15].I += 4;
1743
+}
1744
+
1745
+void CPUSoftwareInterrupt(int comment)
1746
+{
1747
+  static bool disableMessage = false;
1748
+  if(armState) comment >>= 16;
1749
+#ifdef BKPT_SUPPORT
1750
+  if(comment == 0xff) {
1751
+    dbgOutput(NULL, reg[0].I);
1752
+    return;
1753
+  }
1754
+#endif
1755
+#ifdef PROFILING
1756
+  if(comment == 0xfe) {
1757
+    profStartup(reg[0].I, reg[1].I);
1758
+    return;
1759
+  }
1760
+  if(comment == 0xfd) {
1761
+    profControl(reg[0].I);
1762
+    return;
1763
+  }
1764
+  if(comment == 0xfc) {
1765
+    profCleanup();
1766
+    return;
1767
+  }
1768
+  if(comment == 0xfb) {
1769
+    profCount();
1770
+    return;
1771
+  }
1772
+#endif
1773
+  if(comment == 0xfa) {
1774
+    //agbPrintFlush();
1775
+    return;
1776
+  }
1777
+#ifdef SDL
1778
+  if(comment == 0xf9) {
1779
+    emulating = 0;
1780
+    cpuNextEvent = cpuTotalTicks;
1781
+    cpuBreakLoop = true;
1782
+    return;
1783
+  }
1784
+#endif
1785
+  if(useBios) {
1786
+#ifdef GBA_LOGGING
1787
+    if(systemVerbose & VERBOSE_SWI) {
1788
+      log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
1789
+          armState ? armNextPC - 4: armNextPC -2,
1790
+          reg[0].I,
1791
+          reg[1].I,
1792
+          reg[2].I,
1793
+          VCOUNT);
1794
+    }
1795
+#endif
1796
+    CPUSoftwareInterrupt();
1797
+    return;
1798
+  }
1799
+  // This would be correct, but it causes problems if uncommented
1800
+  //  else {
1801
+  //    biosProtected = 0xe3a02004;
1802
+  //  }
1803
+
1804
+  switch(comment) {
1805
+  case 0x00:
1806
+    BIOS_SoftReset();
1807
+    ARM_PREFETCH;
1808
+    break;
1809
+  case 0x01:
1810
+    BIOS_RegisterRamReset();
1811
+    break;
1812
+  case 0x02:
1813
+#ifdef GBA_LOGGING
1814
+    if(systemVerbose & VERBOSE_SWI) {
1815
+      log("Halt: (VCOUNT = %2d)\n",
1816
+          VCOUNT);
1817
+    }
1818
+#endif
1819
+    holdState = true;
1820
+    holdType = -1;
1821
+    cpuNextEvent = cpuTotalTicks;
1822
+    break;
1823
+  case 0x03:
1824
+#ifdef GBA_LOGGING
1825
+    if(systemVerbose & VERBOSE_SWI) {
1826
+      log("Stop: (VCOUNT = %2d)\n",
1827
+          VCOUNT);
1828
+    }
1829
+#endif
1830
+    holdState = true;
1831
+    holdType = -1;
1832
+    stopState = true;
1833
+    cpuNextEvent = cpuTotalTicks;
1834
+    break;
1835
+  case 0x04:
1836
+#ifdef GBA_LOGGING
1837
+    if(systemVerbose & VERBOSE_SWI) {
1838
+      log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n",
1839
+          reg[0].I,
1840
+          reg[1].I,
1841
+          VCOUNT);
1842
+    }
1843
+#endif
1844
+    CPUSoftwareInterrupt();
1845
+    break;
1846
+  case 0x05:
1847
+#ifdef GBA_LOGGING
1848
+    if(systemVerbose & VERBOSE_SWI) {
1849
+      log("VBlankIntrWait: (VCOUNT = %2d)\n",
1850
+          VCOUNT);
1851
+    }
1852
+#endif
1853
+    CPUSoftwareInterrupt();
1854
+    break;
1855
+  case 0x06:
1856
+    CPUSoftwareInterrupt();
1857
+    break;
1858
+  case 0x07:
1859
+    CPUSoftwareInterrupt();
1860
+    break;
1861
+  case 0x08:
1862
+    BIOS_Sqrt();
1863
+    break;
1864
+  case 0x09:
1865
+    BIOS_ArcTan();
1866
+    break;
1867
+  case 0x0A:
1868
+    BIOS_ArcTan2();
1869
+    break;
1870
+  case 0x0B:
1871
+    {
1872
+      int len = (reg[2].I & 0x1FFFFF) >>1;
1873
+      if (!(((reg[0].I & 0xe000000) == 0) ||
1874
+         ((reg[0].I + len) & 0xe000000) == 0))
1875
+      {
1876
+        if ((reg[2].I >> 24) & 1)
1877
+        {
1878
+          if ((reg[2].I >> 26) & 1)
1879
+          SWITicks = (7 + memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1);
1880
+          else
1881
+          SWITicks = (8 + memoryWait[(reg[1].I>>24) & 0xF]) * (len);
1882
+        }
1883
+        else
1884
+        {
1885
+          if ((reg[2].I >> 26) & 1)
1886
+          SWITicks = (10 + memoryWait32[(reg[0].I>>24) & 0xF] +
1887
+              memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1);
1888
+          else
1889
+          SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] +
1890
+              memoryWait[(reg[1].I>>24) & 0xF]) * len;
1891
+        }
1892
+      }
1893
+    }
1894
+    BIOS_CpuSet();
1895
+    break;
1896
+  case 0x0C:
1897
+    {
1898
+      int len = (reg[2].I & 0x1FFFFF) >>5;
1899
+      if (!(((reg[0].I & 0xe000000) == 0) ||
1900
+         ((reg[0].I + len) & 0xe000000) == 0))
1901
+      {
1902
+        if ((reg[2].I >> 24) & 1)
1903
+          SWITicks = (6 + memoryWait32[(reg[1].I>>24) & 0xF] +
1904
+              7 * (memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 1)) * len;
1905
+        else
1906
+          SWITicks = (9 + memoryWait32[(reg[0].I>>24) & 0xF] +
1907
+              memoryWait32[(reg[1].I>>24) & 0xF] +
1908
+              7 * (memoryWaitSeq32[(reg[0].I>>24) & 0xF] +
1909
+              memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 2)) * len;
1910
+      }
1911
+    }
1912
+    BIOS_CpuFastSet();
1913
+    break;
1914
+  case 0x0D:
1915
+    BIOS_GetBiosChecksum();
1916
+    break;
1917
+  case 0x0E:
1918
+    BIOS_BgAffineSet();
1919
+    break;
1920
+  case 0x0F:
1921
+    BIOS_ObjAffineSet();
1922
+    break;
1923
+  case 0x10:
1924
+    {
1925
+      int len = CPUReadHalfWord(reg[2].I);
1926
+      if (!(((reg[0].I & 0xe000000) == 0) ||
1927
+         ((reg[0].I + len) & 0xe000000) == 0))
1928
+        SWITicks = (32 + memoryWait[(reg[0].I>>24) & 0xF]) * len;
1929
+    }
1930
+    BIOS_BitUnPack();
1931
+    break;
1932
+  case 0x11:
1933
+    {
1934
+      u32 len = CPUReadMemory(reg[0].I) >> 8;
1935
+      if(!(((reg[0].I & 0xe000000) == 0) ||
1936
+          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1937
+        SWITicks = (9 + memoryWait[(reg[1].I>>24) & 0xF]) * len;
1938
+    }
1939
+    BIOS_LZ77UnCompWram();
1940
+    break;
1941
+  case 0x12:
1942
+    {
1943
+      u32 len = CPUReadMemory(reg[0].I) >> 8;
1944
+      if(!(((reg[0].I & 0xe000000) == 0) ||
1945
+          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1946
+        SWITicks = (19 + memoryWait[(reg[1].I>>24) & 0xF]) * len;
1947
+    }
1948
+    BIOS_LZ77UnCompVram();
1949
+    break;
1950
+  case 0x13:
1951
+    {
1952
+      u32 len = CPUReadMemory(reg[0].I) >> 8;
1953
+      if(!(((reg[0].I & 0xe000000) == 0) ||
1954
+          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1955
+        SWITicks = (29 + (memoryWait[(reg[0].I>>24) & 0xF]<<1)) * len;
1956
+    }
1957
+    BIOS_HuffUnComp();
1958
+    break;
1959
+  case 0x14:
1960
+    {
1961
+      u32 len = CPUReadMemory(reg[0].I) >> 8;
1962
+      if(!(((reg[0].I & 0xe000000) == 0) ||
1963
+          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1964
+        SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] +
1965
+          memoryWait[(reg[1].I>>24) & 0xF]) * len;
1966
+    }
1967
+    BIOS_RLUnCompWram();
1968
+    break;
1969
+  case 0x15:
1970
+    {
1971
+      u32 len = CPUReadMemory(reg[0].I) >> 9;
1972
+      if(!(((reg[0].I & 0xe000000) == 0) ||
1973
+          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1974
+        SWITicks = (34 + (memoryWait[(reg[0].I>>24) & 0xF] << 1) +
1975
+          memoryWait[(reg[1].I>>24) & 0xF]) * len;
1976
+    }
1977
+    BIOS_RLUnCompVram();
1978
+    break;
1979
+  case 0x16:
1980
+    {
1981
+      u32 len = CPUReadMemory(reg[0].I) >> 8;
1982
+      if(!(((reg[0].I & 0xe000000) == 0) ||
1983
+          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1984
+        SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] +
1985
+          memoryWait[(reg[1].I>>24) & 0xF]) * len;
1986
+    }
1987
+    BIOS_Diff8bitUnFilterWram();
1988
+    break;
1989
+  case 0x17:
1990
+    {
1991
+      u32 len = CPUReadMemory(reg[0].I) >> 9;
1992
+      if(!(((reg[0].I & 0xe000000) == 0) ||
1993
+          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
1994
+        SWITicks = (39 + (memoryWait[(reg[0].I>>24) & 0xF]<<1) +
1995
+          memoryWait[(reg[1].I>>24) & 0xF]) * len;
1996
+    }
1997
+    BIOS_Diff8bitUnFilterVram();
1998
+    break;
1999
+  case 0x18:
2000
+    {
2001
+      u32 len = CPUReadMemory(reg[0].I) >> 9;
2002
+      if(!(((reg[0].I & 0xe000000) == 0) ||
2003
+          ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
2004
+        SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] +
2005
+          memoryWait[(reg[1].I>>24) & 0xF]) * len;
2006
+    }
2007
+    BIOS_Diff16bitUnFilter();
2008
+    break;
2009
+  case 0x19:
2010
+#ifdef GBA_LOGGING
2011
+    if(systemVerbose & VERBOSE_SWI) {
2012
+      log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n",
2013
+          reg[0].I,
2014
+          VCOUNT);
2015
+    }
2016
+#endif
2017
+    if(reg[0].I)
2018
+      soundPause();
2019
+    else
2020
+      soundResume();
2021
+    break;
2022
+  case 0x1F:
2023
+    BIOS_MidiKey2Freq();
2024
+    break;
2025
+  case 0x2A:
2026
+    BIOS_SndDriverJmpTableCopy();
2027
+    // let it go, because we don't really emulate this function
2028
+  default:
2029
+#ifdef GBA_LOGGING
2030
+    if(systemVerbose & VERBOSE_SWI) {
2031
+      log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
2032
+          armState ? armNextPC - 4: armNextPC -2,
2033
+          reg[0].I,
2034
+          reg[1].I,
2035
+          reg[2].I,
2036
+          VCOUNT);
2037
+    }
2038
+#endif
2039
+
2040
+    if(!disableMessage) {
2041
+      /*systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION,
2042
+                    N_("Unsupported BIOS function %02x called from %08x. A BIOS file is needed in order to get correct behaviour."),
2043
+                    comment,
2044
+                    armMode ? armNextPC - 4: armNextPC - 2);*/
2045
+      disableMessage = true;
2046
+    }
2047
+    break;
2048
+  }
2049
+}
2050
+
2051
+void CPUCompareVCOUNT()
2052
+{
2053
+  if(VCOUNT == (DISPSTAT >> 8)) {
2054
+    DISPSTAT |= 4;
2055
+    UPDATE_REG(0x04, DISPSTAT);
2056
+
2057
+    if(DISPSTAT & 0x20) {
2058
+      IF |= 4;
2059
+      UPDATE_REG(0x202, IF);
2060
+    }
2061
+  } else {
2062
+    DISPSTAT &= 0xFFFB;
2063
+    UPDATE_REG(0x4, DISPSTAT);
2064
+  }
2065
+  if (layerEnableDelay>0)
2066
+  {
2067
+      layerEnableDelay--;
2068
+      if (layerEnableDelay==1)
2069
+          layerEnable = layerSettings & DISPCNT;
2070
+  }
2071
+
2072
+}
2073
+
2074
+void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
2075
+{
2076
+  int sm = s >> 24;
2077
+  int dm = d >> 24;
2078
+  int sw = 0;
2079
+  int dw = 0;
2080
+  int sc = c;
2081
+
2082
+  cpuDmaCount = c;
2083
+  // This is done to get the correct waitstates.
2084
+  if (sm>15)
2085
+      sm=15;
2086
+  if (dm>15)
2087
+      dm=15;
2088
+
2089
+  //if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07))
2090
+  //    blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ?  true : false);
2091
+
2092
+  if(transfer32) {
2093
+    s &= 0xFFFFFFFC;
2094
+    if(s < 0x02000000 && (reg[15].I >> 24)) {
2095
+      while(c != 0) {
2096
+        CPUWriteMemory(d, 0);
2097
+        d += di;
2098
+        c--;
2099
+      }
2100
+    } else {
2101
+      while(c != 0) {
2102
+        cpuDmaLast = CPUReadMemory(s);
2103
+        CPUWriteMemory(d, cpuDmaLast);
2104
+        d += di;
2105
+        s += si;
2106
+        c--;
2107
+      }
2108
+    }
2109
+  } else {
2110
+    s &= 0xFFFFFFFE;
2111
+    si = (int)si >> 1;
2112
+    di = (int)di >> 1;
2113
+    if(s < 0x02000000 && (reg[15].I >> 24)) {
2114
+      while(c != 0) {
2115
+        CPUWriteHalfWord(d, 0);
2116
+        d += di;
2117
+        c--;
2118
+      }
2119
+    } else {
2120
+      while(c != 0) {
2121
+        cpuDmaLast = CPUReadHalfWord(s);
2122
+        CPUWriteHalfWord(d, cpuDmaLast);
2123
+        cpuDmaLast |= (cpuDmaLast<<16);
2124
+        d += di;
2125
+        s += si;
2126
+        c--;
2127
+      }
2128
+    }
2129
+  }
2130
+
2131
+  cpuDmaCount = 0;
2132
+
2133
+  int totalTicks = 0;
2134
+
2135
+  if(transfer32) {
2136
+      sw =1+memoryWaitSeq32[sm & 15];
2137
+      dw =1+memoryWaitSeq32[dm & 15];
2138
+      totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait32[sm & 15] +
2139
+          memoryWaitSeq32[dm & 15];
2140
+  }
2141
+  else
2142
+  {
2143
+     sw = 1+memoryWaitSeq[sm & 15];
2144
+     dw = 1+memoryWaitSeq[dm & 15];
2145
+      totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait[sm & 15] +
2146
+          memoryWaitSeq[dm & 15];
2147
+  }
2148
+
2149
+  cpuDmaTicksToUpdate += totalTicks;
2150
+
2151
+}
2152
+
2153
+void CPUCheckDMA(int reason, int dmamask)
2154
+{
2155
+  // DMA 0
2156
+  if((DM0CNT_H & 0x8000) && (dmamask & 1)) {
2157
+    if(((DM0CNT_H >> 12) & 3) == reason) {
2158
+      u32 sourceIncrement = 4;
2159
+      u32 destIncrement = 4;
2160
+      switch((DM0CNT_H >> 7) & 3) {
2161
+      case 0:
2162
+        break;
2163
+      case 1:
2164
+        sourceIncrement = (u32)-4;
2165
+        break;
2166
+      case 2:
2167
+        sourceIncrement = 0;
2168
+        break;
2169
+      }
2170
+      switch((DM0CNT_H >> 5) & 3) {
2171
+      case 0:
2172
+        break;
2173
+      case 1:
2174
+        destIncrement = (u32)-4;
2175
+        break;
2176
+      case 2:
2177
+        destIncrement = 0;
2178
+        break;
2179
+      }
2180
+#ifdef GBA_LOGGING
2181
+      if(systemVerbose & VERBOSE_DMA0) {
2182
+        int count = (DM0CNT_L ? DM0CNT_L : 0x4000) << 1;
2183
+        if(DM0CNT_H & 0x0400)
2184
+          count <<= 1;
2185
+        log("DMA0: s=%08x d=%08x c=%04x count=%08x\n", dma0Source, dma0Dest,
2186
+            DM0CNT_H,
2187
+            count);
2188
+      }
2189
+#endif
2190
+      doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement,
2191
+            DM0CNT_L ? DM0CNT_L : 0x4000,
2192
+            DM0CNT_H & 0x0400);
2193
+      cpuDmaHack = true;
2194
+
2195
+      if(DM0CNT_H & 0x4000) {
2196
+        IF |= 0x0100;
2197
+        UPDATE_REG(0x202, IF);
2198
+        cpuNextEvent = cpuTotalTicks;
2199
+      }
2200
+
2201
+      if(((DM0CNT_H >> 5) & 3) == 3) {
2202
+        dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
2203
+      }
2204
+
2205
+      if(!(DM0CNT_H & 0x0200) || (reason == 0)) {
2206
+        DM0CNT_H &= 0x7FFF;
2207
+        UPDATE_REG(0xBA, DM0CNT_H);
2208
+      }
2209
+    }
2210
+  }
2211
+
2212
+  // DMA 1
2213
+  if((DM1CNT_H & 0x8000) && (dmamask & 2)) {
2214
+    if(((DM1CNT_H >> 12) & 3) == reason) {
2215
+      u32 sourceIncrement = 4;
2216
+      u32 destIncrement = 4;
2217
+      switch((DM1CNT_H >> 7) & 3) {
2218
+      case 0:
2219
+        break;
2220
+      case 1:
2221
+        sourceIncrement = (u32)-4;
2222
+        break;
2223
+      case 2:
2224
+        sourceIncrement = 0;
2225
+        break;
2226
+      }
2227
+      switch((DM1CNT_H >> 5) & 3) {
2228
+      case 0:
2229
+        break;
2230
+      case 1:
2231
+        destIncrement = (u32)-4;
2232
+        break;
2233
+      case 2:
2234
+        destIncrement = 0;
2235
+        break;
2236
+      }
2237
+      if(reason == 3) {
2238
+#ifdef GBA_LOGGING
2239
+        if(systemVerbose & VERBOSE_DMA1) {
2240
+          log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
2241
+              DM1CNT_H,
2242
+              16);
2243
+        }
2244
+#endif
2245
+        doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4,
2246
+              0x0400);
2247
+      } else {
2248
+#ifdef GBA_LOGGING
2249
+        if(systemVerbose & VERBOSE_DMA1) {
2250
+          int count = (DM1CNT_L ? DM1CNT_L : 0x4000) << 1;
2251
+          if(DM1CNT_H & 0x0400)
2252
+            count <<= 1;
2253
+          log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
2254
+              DM1CNT_H,
2255
+              count);
2256
+        }
2257
+#endif
2258
+        doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement,
2259
+              DM1CNT_L ? DM1CNT_L : 0x4000,
2260
+              DM1CNT_H & 0x0400);
2261
+      }
2262
+      cpuDmaHack = true;
2263
+
2264
+      if(DM1CNT_H & 0x4000) {
2265
+        IF |= 0x0200;
2266
+        UPDATE_REG(0x202, IF);
2267
+        cpuNextEvent = cpuTotalTicks;
2268
+      }
2269
+
2270
+      if(((DM1CNT_H >> 5) & 3) == 3) {
2271
+        dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
2272
+      }
2273
+
2274
+      if(!(DM1CNT_H & 0x0200) || (reason == 0)) {
2275
+        DM1CNT_H &= 0x7FFF;
2276
+        UPDATE_REG(0xC6, DM1CNT_H);
2277
+      }
2278
+    }
2279
+  }
2280
+
2281
+  // DMA 2
2282
+  if((DM2CNT_H & 0x8000) && (dmamask & 4)) {
2283
+    if(((DM2CNT_H >> 12) & 3) == reason) {
2284
+      u32 sourceIncrement = 4;
2285
+      u32 destIncrement = 4;
2286
+      switch((DM2CNT_H >> 7) & 3) {
2287
+      case 0:
2288
+        break;
2289
+      case 1:
2290
+        sourceIncrement = (u32)-4;
2291
+        break;
2292
+      case 2:
2293
+        sourceIncrement = 0;
2294
+        break;
2295
+      }
2296
+      switch((DM2CNT_H >> 5) & 3) {
2297
+      case 0:
2298
+        break;
2299
+      case 1:
2300
+        destIncrement = (u32)-4;
2301
+        break;
2302
+      case 2:
2303
+        destIncrement = 0;
2304
+        break;
2305
+      }
2306
+      if(reason == 3) {
2307
+#ifdef GBA_LOGGING
2308
+        if(systemVerbose & VERBOSE_DMA2) {
2309
+          int count = (4) << 2;
2310
+          log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
2311
+              DM2CNT_H,
2312
+              count);
2313
+        }
2314
+#endif
2315
+        doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4,
2316
+              0x0400);
2317
+      } else {
2318
+#ifdef GBA_LOGGING
2319
+        if(systemVerbose & VERBOSE_DMA2) {
2320
+          int count = (DM2CNT_L ? DM2CNT_L : 0x4000) << 1;
2321
+          if(DM2CNT_H & 0x0400)
2322
+            count <<= 1;
2323
+          log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
2324
+              DM2CNT_H,
2325
+              count);
2326
+        }
2327
+#endif
2328
+        doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement,
2329
+              DM2CNT_L ? DM2CNT_L : 0x4000,
2330
+              DM2CNT_H & 0x0400);
2331
+      }
2332
+      cpuDmaHack = true;
2333
+
2334
+      if(DM2CNT_H & 0x4000) {
2335
+        IF |= 0x0400;
2336
+        UPDATE_REG(0x202, IF);
2337
+        cpuNextEvent = cpuTotalTicks;
2338
+      }
2339
+
2340
+      if(((DM2CNT_H >> 5) & 3) == 3) {
2341
+        dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
2342
+      }
2343
+
2344
+      if(!(DM2CNT_H & 0x0200) || (reason == 0)) {
2345
+        DM2CNT_H &= 0x7FFF;
2346
+        UPDATE_REG(0xD2, DM2CNT_H);
2347
+      }
2348
+    }
2349
+  }
2350
+
2351
+  // DMA 3
2352
+  if((DM3CNT_H & 0x8000) && (dmamask & 8)) {
2353
+    if(((DM3CNT_H >> 12) & 3) == reason) {
2354
+      u32 sourceIncrement = 4;
2355
+      u32 destIncrement = 4;
2356
+      switch((DM3CNT_H >> 7) & 3) {
2357
+      case 0:
2358
+        break;
2359
+      case 1:
2360
+        sourceIncrement = (u32)-4;
2361
+        break;
2362
+      case 2:
2363
+        sourceIncrement = 0;
2364
+        break;
2365
+      }
2366
+      switch((DM3CNT_H >> 5) & 3) {
2367
+      case 0:
2368
+        break;
2369
+      case 1:
2370
+        destIncrement = (u32)-4;
2371
+        break;
2372
+      case 2:
2373
+        destIncrement = 0;
2374
+        break;
2375
+      }
2376
+#ifdef GBA_LOGGING
2377
+      if(systemVerbose & VERBOSE_DMA3) {
2378
+        int count = (DM3CNT_L ? DM3CNT_L : 0x10000) << 1;
2379
+        if(DM3CNT_H & 0x0400)
2380
+          count <<= 1;
2381
+        log("DMA3: s=%08x d=%08x c=%04x count=%08x\n", dma3Source, dma3Dest,
2382
+            DM3CNT_H,
2383
+            count);
2384
+      }
2385
+#endif
2386
+      doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement,
2387
+            DM3CNT_L ? DM3CNT_L : 0x10000,
2388
+            DM3CNT_H & 0x0400);
2389
+      if(DM3CNT_H & 0x4000) {
2390
+        IF |= 0x0800;
2391
+        UPDATE_REG(0x202, IF);
2392
+        cpuNextEvent = cpuTotalTicks;
2393
+      }
2394
+
2395
+      if(((DM3CNT_H >> 5) & 3) == 3) {
2396
+        dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
2397
+      }
2398
+
2399
+      if(!(DM3CNT_H & 0x0200) || (reason == 0)) {
2400
+        DM3CNT_H &= 0x7FFF;
2401
+        UPDATE_REG(0xDE, DM3CNT_H);
2402
+      }
2403
+    }
2404
+  }
2405
+}
2406
+
2407
+void CPUUpdateRegister(u32 address, u16 value)
2408
+{
2409
+  switch(address)
2410
+  {
2411
+  case 0x00:
2412
+    { // we need to place the following code in { } because we declare & initialize variables in a case statement
2413
+      if((value & 7) > 5) {
2414
+        // display modes above 0-5 are prohibited
2415
+        DISPCNT = (value & 7);
2416
+      }
2417
+      bool change = (0 != ((DISPCNT ^ value) & 0x80));
2418
+      bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00));
2419
+      u16 changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated
2420
+
2421
+      DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode
2422
+      UPDATE_REG(0x00, DISPCNT);
2423
+
2424
+      if(changeBGon) {
2425
+        layerEnableDelay = 4;
2426
+        layerEnable = layerSettings & value & (~changeBGon);
2427
+      } else {
2428
+        layerEnable = layerSettings & value;
2429
+        // CPUUpdateTicks();
2430
+      }
2431
+
2432
+      windowOn = (layerEnable & 0x6000) ? true : false;
2433
+      if(change && !((value & 0x80))) {
2434
+        if(!(DISPSTAT & 1)) {
2435
+          lcdTicks = 1008;
2436
+          //      VCOUNT = 0;
2437
+          //      UPDATE_REG(0x06, VCOUNT);
2438
+          DISPSTAT &= 0xFFFC;
2439
+          UPDATE_REG(0x04, DISPSTAT);
2440
+          CPUCompareVCOUNT();
2441
+        }
2442
+        //        (*renderLine)();
2443
+      }
2444
+      //CPUUpdateRender();
2445
+      // we only care about changes in BG0-BG3
2446
+      if(changeBG) {
2447
+        //CPUUpdateRenderBuffers(false);
2448
+      }
2449
+      break;
2450
+    }
2451
+  case 0x04:
2452
+    DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7);
2453
+    UPDATE_REG(0x04, DISPSTAT);
2454
+    break;
2455
+  case 0x06:
2456
+    // not writable
2457
+    break;
2458
+  case 0x08:
2459
+    BG0CNT = (value & 0xDFCF);
2460
+    UPDATE_REG(0x08, BG0CNT);
2461
+    break;
2462
+  case 0x0A:
2463
+    BG1CNT = (value & 0xDFCF);
2464
+    UPDATE_REG(0x0A, BG1CNT);
2465
+    break;
2466
+  case 0x0C:
2467
+    BG2CNT = (value & 0xFFCF);
2468
+    UPDATE_REG(0x0C, BG2CNT);
2469
+    break;
2470
+  case 0x0E:
2471
+    BG3CNT = (value & 0xFFCF);
2472
+    UPDATE_REG(0x0E, BG3CNT);
2473
+    break;
2474
+  case 0x10:
2475
+    BG0HOFS = value & 511;
2476
+    UPDATE_REG(0x10, BG0HOFS);
2477
+    break;
2478
+  case 0x12:
2479
+    BG0VOFS = value & 511;
2480
+    UPDATE_REG(0x12, BG0VOFS);
2481
+    break;
2482
+  case 0x14:
2483
+    BG1HOFS = value & 511;
2484
+    UPDATE_REG(0x14, BG1HOFS);
2485
+    break;
2486
+  case 0x16:
2487
+    BG1VOFS = value & 511;
2488
+    UPDATE_REG(0x16, BG1VOFS);
2489
+    break;
2490
+  case 0x18:
2491
+    BG2HOFS = value & 511;
2492
+    UPDATE_REG(0x18, BG2HOFS);
2493
+    break;
2494
+  case 0x1A:
2495
+    BG2VOFS = value & 511;
2496
+    UPDATE_REG(0x1A, BG2VOFS);
2497
+    break;
2498
+  case 0x1C:
2499
+    BG3HOFS = value & 511;
2500
+    UPDATE_REG(0x1C, BG3HOFS);
2501
+    break;
2502
+  case 0x1E:
2503
+    BG3VOFS = value & 511;
2504
+    UPDATE_REG(0x1E, BG3VOFS);
2505
+    break;
2506
+  case 0x20:
2507
+    BG2PA = value;
2508
+    UPDATE_REG(0x20, BG2PA);
2509
+    break;
2510
+  case 0x22:
2511
+    BG2PB = value;
2512
+    UPDATE_REG(0x22, BG2PB);
2513
+    break;
2514
+  case 0x24:
2515
+    BG2PC = value;
2516
+    UPDATE_REG(0x24, BG2PC);
2517
+    break;
2518
+  case 0x26:
2519
+    BG2PD = value;
2520
+    UPDATE_REG(0x26, BG2PD);
2521
+    break;
2522
+  case 0x28:
2523
+    BG2X_L = value;
2524
+    UPDATE_REG(0x28, BG2X_L);
2525
+    //gfxBG2Changed |= 1;
2526
+    break;
2527
+  case 0x2A:
2528
+    BG2X_H = (value & 0xFFF);
2529
+    UPDATE_REG(0x2A, BG2X_H);
2530
+    //gfxBG2Changed |= 1;
2531
+    break;
2532
+  case 0x2C:
2533
+    BG2Y_L = value;
2534
+    UPDATE_REG(0x2C, BG2Y_L);
2535
+    //gfxBG2Changed |= 2;
2536
+    break;
2537
+  case 0x2E:
2538
+    BG2Y_H = value & 0xFFF;
2539
+    UPDATE_REG(0x2E, BG2Y_H);
2540
+    //gfxBG2Changed |= 2;
2541
+    break;
2542
+  case 0x30:
2543
+    BG3PA = value;
2544
+    UPDATE_REG(0x30, BG3PA);
2545
+    break;
2546
+  case 0x32:
2547
+    BG3PB = value;
2548
+    UPDATE_REG(0x32, BG3PB);
2549
+    break;
2550
+  case 0x34:
2551
+    BG3PC = value;
2552
+    UPDATE_REG(0x34, BG3PC);
2553
+    break;
2554
+  case 0x36:
2555
+    BG3PD = value;
2556
+    UPDATE_REG(0x36, BG3PD);
2557
+    break;
2558
+  case 0x38:
2559
+    BG3X_L = value;
2560
+    UPDATE_REG(0x38, BG3X_L);
2561
+    //gfxBG3Changed |= 1;
2562
+    break;
2563
+  case 0x3A:
2564
+    BG3X_H = value & 0xFFF;
2565
+    UPDATE_REG(0x3A, BG3X_H);
2566
+    //gfxBG3Changed |= 1;
2567
+    break;
2568
+  case 0x3C:
2569
+    BG3Y_L = value;
2570
+    UPDATE_REG(0x3C, BG3Y_L);
2571
+    //gfxBG3Changed |= 2;
2572
+    break;
2573
+  case 0x3E:
2574
+    BG3Y_H = value & 0xFFF;
2575
+    UPDATE_REG(0x3E, BG3Y_H);
2576
+    //gfxBG3Changed |= 2;
2577
+    break;
2578
+  case 0x40:
2579
+    WIN0H = value;
2580
+    UPDATE_REG(0x40, WIN0H);
2581
+    //CPUUpdateWindow0();
2582
+    break;
2583
+  case 0x42:
2584
+    WIN1H = value;
2585
+    UPDATE_REG(0x42, WIN1H);
2586
+    //CPUUpdateWindow1();
2587
+    break;
2588
+  case 0x44:
2589
+    WIN0V = value;
2590
+    UPDATE_REG(0x44, WIN0V);
2591
+    break;
2592
+  case 0x46:
2593
+    WIN1V = value;
2594
+    UPDATE_REG(0x46, WIN1V);
2595
+    break;
2596
+  case 0x48:
2597
+    WININ = value & 0x3F3F;
2598
+    UPDATE_REG(0x48, WININ);
2599
+    break;
2600
+  case 0x4A:
2601
+    WINOUT = value & 0x3F3F;
2602
+    UPDATE_REG(0x4A, WINOUT);
2603
+    break;
2604
+  case 0x4C:
2605
+    MOSAIC = value;
2606
+    UPDATE_REG(0x4C, MOSAIC);
2607
+    break;
2608
+  case 0x50:
2609
+    BLDMOD = value & 0x3FFF;
2610
+    UPDATE_REG(0x50, BLDMOD);
2611
+    fxOn = ((BLDMOD>>6)&3) != 0;
2612
+    //CPUUpdateRender();
2613
+    break;
2614
+  case 0x52:
2615
+    COLEV = value & 0x1F1F;
2616
+    UPDATE_REG(0x52, COLEV);
2617
+    break;
2618
+  case 0x54:
2619
+    COLY = value & 0x1F;
2620
+    UPDATE_REG(0x54, COLY);
2621
+    break;
2622
+  case 0x60:
2623
+  case 0x62:
2624
+  case 0x64:
2625
+  case 0x68:
2626
+  case 0x6c:
2627
+  case 0x70:
2628
+  case 0x72:
2629
+  case 0x74:
2630
+  case 0x78:
2631
+  case 0x7c:
2632
+  case 0x80:
2633
+  case 0x84:
2634
+    soundEvent(address&0xFF, (u8)(value & 0xFF));
2635
+    soundEvent((address&0xFF)+1, (u8)(value>>8));
2636
+    break;
2637
+  case 0x82:
2638
+  case 0x88:
2639
+  case 0xa0:
2640
+  case 0xa2:
2641
+  case 0xa4:
2642
+  case 0xa6:
2643
+  case 0x90:
2644
+  case 0x92:
2645
+  case 0x94:
2646
+  case 0x96:
2647
+  case 0x98:
2648
+  case 0x9a:
2649
+  case 0x9c:
2650
+  case 0x9e:
2651
+    soundEvent(address&0xFF, value);
2652
+    break;
2653
+  case 0xB0:
2654
+    DM0SAD_L = value;
2655
+    UPDATE_REG(0xB0, DM0SAD_L);
2656
+    break;
2657
+  case 0xB2:
2658
+    DM0SAD_H = value & 0x07FF;
2659
+    UPDATE_REG(0xB2, DM0SAD_H);
2660
+    break;
2661
+  case 0xB4:
2662
+    DM0DAD_L = value;
2663
+    UPDATE_REG(0xB4, DM0DAD_L);
2664
+    break;
2665
+  case 0xB6:
2666
+    DM0DAD_H = value & 0x07FF;
2667
+    UPDATE_REG(0xB6, DM0DAD_H);
2668
+    break;
2669
+  case 0xB8:
2670
+    DM0CNT_L = value & 0x3FFF;
2671
+    UPDATE_REG(0xB8, 0);
2672
+    break;
2673
+  case 0xBA:
2674
+    {
2675
+      bool start = ((DM0CNT_H ^ value) & 0x8000) ? true : false;
2676
+      value &= 0xF7E0;
2677
+
2678
+      DM0CNT_H = value;
2679
+      UPDATE_REG(0xBA, DM0CNT_H);
2680
+
2681
+      if(start && (value & 0x8000)) {
2682
+        dma0Source = DM0SAD_L | (DM0SAD_H << 16);
2683
+        dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
2684
+        CPUCheckDMA(0, 1);
2685
+      }
2686
+    }
2687
+    break;
2688
+  case 0xBC:
2689
+    DM1SAD_L = value;
2690
+    UPDATE_REG(0xBC, DM1SAD_L);
2691
+    break;
2692
+  case 0xBE:
2693
+    DM1SAD_H = value & 0x0FFF;
2694
+    UPDATE_REG(0xBE, DM1SAD_H);
2695
+    break;
2696
+  case 0xC0:
2697
+    DM1DAD_L = value;
2698
+    UPDATE_REG(0xC0, DM1DAD_L);
2699
+    break;
2700
+  case 0xC2:
2701
+    DM1DAD_H = value & 0x07FF;
2702
+    UPDATE_REG(0xC2, DM1DAD_H);
2703
+    break;
2704
+  case 0xC4:
2705
+    DM1CNT_L = value & 0x3FFF;
2706
+    UPDATE_REG(0xC4, 0);
2707
+    break;
2708
+  case 0xC6:
2709
+    {
2710
+      bool start = ((DM1CNT_H ^ value) & 0x8000) ? true : false;
2711
+      value &= 0xF7E0;
2712
+
2713
+      DM1CNT_H = value;
2714
+      UPDATE_REG(0xC6, DM1CNT_H);
2715
+
2716
+      if(start && (value & 0x8000)) {
2717
+        dma1Source = DM1SAD_L | (DM1SAD_H << 16);
2718
+        dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
2719
+        CPUCheckDMA(0, 2);
2720
+      }
2721
+    }
2722
+    break;
2723
+  case 0xC8:
2724
+    DM2SAD_L = value;
2725
+    UPDATE_REG(0xC8, DM2SAD_L);
2726
+    break;
2727
+  case 0xCA:
2728
+    DM2SAD_H = value & 0x0FFF;
2729
+    UPDATE_REG(0xCA, DM2SAD_H);
2730
+    break;
2731
+  case 0xCC:
2732
+    DM2DAD_L = value;
2733
+    UPDATE_REG(0xCC, DM2DAD_L);
2734
+    break;
2735
+  case 0xCE:
2736
+    DM2DAD_H = value & 0x07FF;
2737
+    UPDATE_REG(0xCE, DM2DAD_H);
2738
+    break;
2739
+  case 0xD0:
2740
+    DM2CNT_L = value & 0x3FFF;
2741
+    UPDATE_REG(0xD0, 0);
2742
+    break;
2743
+  case 0xD2:
2744
+    {
2745
+      bool start = ((DM2CNT_H ^ value) & 0x8000) ? true : false;
2746
+
2747
+      value &= 0xF7E0;
2748
+
2749
+      DM2CNT_H = value;
2750
+      UPDATE_REG(0xD2, DM2CNT_H);
2751
+
2752
+      if(start && (value & 0x8000)) {
2753
+        dma2Source = DM2SAD_L | (DM2SAD_H << 16);
2754
+        dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
2755
+
2756
+        CPUCheckDMA(0, 4);
2757
+      }
2758
+    }
2759
+    break;
2760
+  case 0xD4:
2761
+    DM3SAD_L = value;
2762
+    UPDATE_REG(0xD4, DM3SAD_L);
2763
+    break;
2764
+  case 0xD6:
2765
+    DM3SAD_H = value & 0x0FFF;
2766
+    UPDATE_REG(0xD6, DM3SAD_H);
2767
+    break;
2768
+  case 0xD8:
2769
+    DM3DAD_L = value;
2770
+    UPDATE_REG(0xD8, DM3DAD_L);
2771
+    break;
2772
+  case 0xDA:
2773
+    DM3DAD_H = value & 0x0FFF;
2774
+    UPDATE_REG(0xDA, DM3DAD_H);
2775
+    break;
2776
+  case 0xDC:
2777
+    DM3CNT_L = value;
2778
+    UPDATE_REG(0xDC, 0);
2779
+    break;
2780
+  case 0xDE:
2781
+    {
2782
+      bool start = ((DM3CNT_H ^ value) & 0x8000) ? true : false;
2783
+
2784
+      value &= 0xFFE0;
2785
+
2786
+      DM3CNT_H = value;
2787
+      UPDATE_REG(0xDE, DM3CNT_H);
2788
+
2789
+      if(start && (value & 0x8000)) {
2790
+        dma3Source = DM3SAD_L | (DM3SAD_H << 16);
2791
+        dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
2792
+        CPUCheckDMA(0,8);
2793
+      }
2794
+    }
2795
+    break;
2796
+  case 0x100:
2797
+    timer0Reload = value;
2798
+    interp_rate();
2799
+    break;
2800
+  case 0x102:
2801
+    timer0Value = value;
2802
+    timerOnOffDelay|=1;
2803
+    cpuNextEvent = cpuTotalTicks;
2804
+    break;
2805
+  case 0x104:
2806
+    timer1Reload = value;
2807
+    interp_rate();
2808
+    break;
2809
+  case 0x106:
2810
+    timer1Value = value;
2811
+    timerOnOffDelay|=2;
2812
+    cpuNextEvent = cpuTotalTicks;
2813
+    break;
2814
+  case 0x108:
2815
+    timer2Reload = value;
2816
+    break;
2817
+  case 0x10A:
2818
+    timer2Value = value;
2819
+    timerOnOffDelay|=4;
2820
+    cpuNextEvent = cpuTotalTicks;
2821
+    break;
2822
+  case 0x10C:
2823
+    timer3Reload = value;
2824
+    break;
2825
+  case 0x10E:
2826
+    timer3Value = value;
2827
+    timerOnOffDelay|=8;
2828
+    cpuNextEvent = cpuTotalTicks;
2829
+    break;
2830
+
2831
+
2832
+  /*case COMM_SIOCNT:
2833
+	  StartLink(value);
2834
+	  break;
2835
+
2836
+  case COMM_SIODATA8:
2837
+	  if (gba_link_enabled)
2838
+		  LinkSSend(value);
2839
+	  UPDATE_REG(COMM_SIODATA8, value);
2840
+	  break;*/
2841
+
2842
+  case 0x130:
2843
+	  P1 |= (value & 0x3FF);
2844
+	  UPDATE_REG(0x130, P1);
2845
+	  break;
2846
+
2847
+  case 0x132:
2848
+	  UPDATE_REG(0x132, value & 0xC3FF);
2849
+	  break;
2850
+
2851
+  /*case COMM_RCNT:
2852
+	  StartGPLink(value);
2853
+	  break;
2854
+
2855
+  case COMM_JOYCNT:
2856
+	  {
2857
+		  u16 cur = READ16LE(&ioMem[COMM_JOYCNT]);
2858
+
2859
+		  if (value & JOYCNT_RESET)			cur &= ~JOYCNT_RESET;
2860
+		  if (value & JOYCNT_RECV_COMPLETE)	cur &= ~JOYCNT_RECV_COMPLETE;
2861
+		  if (value & JOYCNT_SEND_COMPLETE)	cur &= ~JOYCNT_SEND_COMPLETE;
2862
+		  if (value & JOYCNT_INT_ENABLE)	cur |= JOYCNT_INT_ENABLE;
2863
+
2864
+		  UPDATE_REG(COMM_JOYCNT, cur);
2865
+	  }
2866
+	  break;
2867
+
2868
+  case COMM_JOY_RECV_L:
2869
+	  UPDATE_REG(COMM_JOY_RECV_L, value);
2870
+	  break;
2871
+  case COMM_JOY_RECV_H:
2872
+	  UPDATE_REG(COMM_JOY_RECV_H, value);
2873
+	  break;
2874
+
2875
+  case COMM_JOY_TRANS_L:
2876
+	  UPDATE_REG(COMM_JOY_TRANS_L, value);
2877
+	  UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND);
2878
+	  break;
2879
+  case COMM_JOY_TRANS_H:
2880
+	  UPDATE_REG(COMM_JOY_TRANS_H, value);
2881
+	  break;
2882
+
2883
+  case COMM_JOYSTAT:
2884
+	  UPDATE_REG(COMM_JOYSTAT, (READ16LE(&ioMem[COMM_JOYSTAT]) & 0xf) | (value & 0xf0));
2885
+	  break;*/
2886
+
2887
+  case 0x200:
2888
+    IE = value & 0x3FFF;
2889
+    UPDATE_REG(0x200, IE);
2890
+    if ((IME & 1) && (IF & IE) && armIrqEnable)
2891
+      cpuNextEvent = cpuTotalTicks;
2892
+    break;
2893
+  case 0x202:
2894
+    IF ^= (value & IF);
2895
+    UPDATE_REG(0x202, IF);
2896
+    break;
2897
+  case 0x204:
2898
+    {
2899
+      memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3];
2900
+
2901
+      if(!speedHack) {
2902
+        memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3];
2903
+        memoryWaitSeq[0x08] = memoryWaitSeq[0x09] =
2904
+          gamepakWaitState0[(value >> 4) & 1];
2905
+
2906
+        memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3];
2907
+        memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] =
2908
+          gamepakWaitState1[(value >> 7) & 1];
2909
+
2910
+        memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3];
2911
+        memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] =
2912
+          gamepakWaitState2[(value >> 10) & 1];
2913
+      } else {
2914
+        memoryWait[0x08] = memoryWait[0x09] = 3;
2915
+        memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = 1;
2916
+
2917
+        memoryWait[0x0a] = memoryWait[0x0b] = 3;
2918
+        memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = 1;
2919
+
2920
+        memoryWait[0x0c] = memoryWait[0x0d] = 3;
2921
+        memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = 1;
2922
+      }
2923
+
2924
+      for(int i = 8; i < 15; i++) {
2925
+        memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1;
2926
+        memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1;
2927
+      }
2928
+
2929
+      if((value & 0x4000) == 0x4000) {
2930
+        busPrefetchEnable = true;
2931
+        busPrefetch = false;
2932
+        busPrefetchCount = 0;
2933
+      } else {
2934
+        busPrefetchEnable = false;
2935
+        busPrefetch = false;
2936
+        busPrefetchCount = 0;
2937
+      }
2938
+      UPDATE_REG(0x204, value & 0x7FFF);
2939
+
2940
+    }
2941
+    break;
2942
+  case 0x208:
2943
+    IME = value & 1;
2944
+    UPDATE_REG(0x208, IME);
2945
+    if ((IME & 1) && (IF & IE) && armIrqEnable)
2946
+      cpuNextEvent = cpuTotalTicks;
2947
+    break;
2948
+  case 0x300:
2949
+    if(value != 0)
2950
+      value &= 0xFFFE;
2951
+    UPDATE_REG(0x300, value);
2952
+    break;
2953
+  default:
2954
+    UPDATE_REG(address&0x3FE, value);
2955
+    break;
2956
+  }
2957
+}
2958
+
2959
+void applyTimer ()
2960
+{
2961
+  if (timerOnOffDelay & 1)
2962
+  {
2963
+    timer0ClockReload = TIMER_TICKS[timer0Value & 3];
2964
+    if(!timer0On && (timer0Value & 0x80)) {
2965
+      // reload the counter
2966
+      TM0D = timer0Reload;
2967
+      timer0Ticks = (0x10000 - TM0D) << timer0ClockReload;
2968
+      UPDATE_REG(0x100, TM0D);
2969
+    }
2970
+    timer0On = timer0Value & 0x80 ? true : false;
2971
+    TM0CNT = timer0Value & 0xC7;
2972
+    interp_rate();
2973
+    UPDATE_REG(0x102, TM0CNT);
2974
+    //    CPUUpdateTicks();
2975
+  }
2976
+  if (timerOnOffDelay & 2)
2977
+  {
2978
+    timer1ClockReload = TIMER_TICKS[timer1Value & 3];
2979
+    if(!timer1On && (timer1Value & 0x80)) {
2980
+      // reload the counter
2981
+      TM1D = timer1Reload;
2982
+      timer1Ticks = (0x10000 - TM1D) << timer1ClockReload;
2983
+      UPDATE_REG(0x104, TM1D);
2984
+    }
2985
+    timer1On = timer1Value & 0x80 ? true : false;
2986
+    TM1CNT = timer1Value & 0xC7;
2987
+    interp_rate();
2988
+    UPDATE_REG(0x106, TM1CNT);
2989
+  }
2990
+  if (timerOnOffDelay & 4)
2991
+  {
2992
+    timer2ClockReload = TIMER_TICKS[timer2Value & 3];
2993
+    if(!timer2On && (timer2Value & 0x80)) {
2994
+      // reload the counter
2995
+      TM2D = timer2Reload;
2996
+      timer2Ticks = (0x10000 - TM2D) << timer2ClockReload;
2997
+      UPDATE_REG(0x108, TM2D);
2998
+    }
2999
+    timer2On = timer2Value & 0x80 ? true : false;
3000
+    TM2CNT = timer2Value & 0xC7;
3001
+    UPDATE_REG(0x10A, TM2CNT);
3002
+  }
3003
+  if (timerOnOffDelay & 8)
3004
+  {
3005
+    timer3ClockReload = TIMER_TICKS[timer3Value & 3];
3006
+    if(!timer3On && (timer3Value & 0x80)) {
3007
+      // reload the counter
3008
+      TM3D = timer3Reload;
3009
+      timer3Ticks = (0x10000 - TM3D) << timer3ClockReload;
3010
+      UPDATE_REG(0x10C, TM3D);
3011
+    }
3012
+    timer3On = timer3Value & 0x80 ? true : false;
3013
+    TM3CNT = timer3Value & 0xC7;
3014
+    UPDATE_REG(0x10E, TM3CNT);
3015
+  }
3016
+  cpuNextEvent = CPUUpdateTicks();
3017
+  timerOnOffDelay = 0;
3018
+}
3019
+
3020
+u8 cpuBitsSet[256];
3021
+u8 cpuLowestBitSet[256];
3022
+
3023
+void CPUInit(const char *biosFileName, bool useBiosFile)
3024
+{
3025
+#ifdef WORDS_BIGENDIAN
3026
+  if(!cpuBiosSwapped) {
3027
+    for(unsigned int i = 0; i < sizeof(myROM)/4; i++) {
3028
+      WRITE32LE(&myROM[i], myROM[i]);
3029
+    }
3030
+    cpuBiosSwapped = true;
3031
+  }
3032
+#endif
3033
+  gbaSaveType = 0;
3034
+  //eepromInUse = 0;
3035
+  saveType = 0;
3036
+  useBios = false;
3037
+
3038
+  /*if(useBiosFile) {
3039
+    int size = 0x4000;
3040
+    if(utilLoad(biosFileName,
3041
+                CPUIsGBABios,
3042
+                bios,
3043
+                size)) {
3044
+      if(size == 0x4000)
3045
+        useBios = true;
3046
+      else
3047
+        systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BIOS file size"));
3048
+    }
3049
+  }*/
3050
+
3051
+  if(!useBios) {
3052
+    memcpy(bios, myROM, sizeof(myROM));
3053
+  }
3054
+
3055
+  int i = 0;
3056
+
3057
+  biosProtected[0] = 0x00;
3058
+  biosProtected[1] = 0xf0;
3059
+  biosProtected[2] = 0x29;
3060
+  biosProtected[3] = 0xe1;
3061
+
3062
+  for(i = 0; i < 256; i++) {
3063
+    int count = 0;
3064
+    int j;
3065
+    for(j = 0; j < 8; j++)
3066
+      if(i & (1 << j))
3067
+        count++;
3068
+    cpuBitsSet[i] = count;
3069
+
3070
+    for(j = 0; j < 8; j++)
3071
+      if(i & (1 << j))
3072
+        break;
3073
+    cpuLowestBitSet[i] = j;
3074
+  }
3075
+
3076
+  for(i = 0; i < 0x400; i++)
3077
+    ioReadable[i] = true;
3078
+  for(i = 0x10; i < 0x48; i++)
3079
+    ioReadable[i] = false;
3080
+  for(i = 0x4c; i < 0x50; i++)
3081
+    ioReadable[i] = false;
3082
+  for(i = 0x54; i < 0x60; i++)
3083
+    ioReadable[i] = false;
3084
+  for(i = 0x8c; i < 0x90; i++)
3085
+    ioReadable[i] = false;
3086
+  for(i = 0xa0; i < 0xb8; i++)
3087
+    ioReadable[i] = false;
3088
+  for(i = 0xbc; i < 0xc4; i++)
3089
+    ioReadable[i] = false;
3090
+  for(i = 0xc8; i < 0xd0; i++)
3091
+    ioReadable[i] = false;
3092
+  for(i = 0xd4; i < 0xdc; i++)
3093
+    ioReadable[i] = false;
3094
+  for(i = 0xe0; i < 0x100; i++)
3095
+    ioReadable[i] = false;
3096
+  for(i = 0x110; i < 0x120; i++)
3097
+    ioReadable[i] = false;
3098
+  for(i = 0x12c; i < 0x130; i++)
3099
+    ioReadable[i] = false;
3100
+  for(i = 0x138; i < 0x140; i++)
3101
+    ioReadable[i] = false;
3102
+  for(i = 0x144; i < 0x150; i++)
3103
+    ioReadable[i] = false;
3104
+  for(i = 0x15c; i < 0x200; i++)
3105
+    ioReadable[i] = false;
3106
+  for(i = 0x20c; i < 0x300; i++)
3107
+    ioReadable[i] = false;
3108
+  for(i = 0x304; i < 0x400; i++)
3109
+    ioReadable[i] = false;
3110
+
3111
+  if(romSize < 0x1fe2000) {
3112
+    *((u16 *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA
3113
+    *((u16 *)&rom[0x1fe209e]) = 0x4770; // BX LR
3114
+  } else {
3115
+    //agbPrintEnable(false);
3116
+  }
3117
+}
3118
+
3119
+void CPUReset()
3120
+{
3121
+  /*if(gbaSaveType == 0) {
3122
+    if(eepromInUse)
3123
+      gbaSaveType = 3;
3124
+    else
3125
+      switch(saveType) {
3126
+      case 1:
3127
+        gbaSaveType = 1;
3128
+        break;
3129
+      case 2:
3130
+        gbaSaveType = 2;
3131
+        break;
3132
+      }
3133
+  }
3134
+  rtcReset();*/
3135
+  // clean registers
3136
+  memset(&reg[0], 0, sizeof(reg));
3137
+  // clean OAM
3138
+  memset(oam, 0, 0x400);
3139
+  // clean palette
3140
+  memset(paletteRAM, 0, 0x400);
3141
+  // clean picture
3142
+  memset(pix, 0, 4*160*240);
3143
+  // clean vram
3144
+  memset(vram, 0, 0x20000);
3145
+  // clean io memory
3146
+  memset(ioMem, 0, 0x400);
3147
+
3148
+  DISPCNT  = 0x0080;
3149
+  DISPSTAT = 0x0000;
3150
+  VCOUNT   = (useBios && !skipBios) ? 0 :0x007E;
3151
+  BG0CNT   = 0x0000;
3152
+  BG1CNT   = 0x0000;
3153
+  BG2CNT   = 0x0000;
3154
+  BG3CNT   = 0x0000;
3155
+  BG0HOFS  = 0x0000;
3156
+  BG0VOFS  = 0x0000;
3157
+  BG1HOFS  = 0x0000;
3158
+  BG1VOFS  = 0x0000;
3159
+  BG2HOFS  = 0x0000;
3160
+  BG2VOFS  = 0x0000;
3161
+  BG3HOFS  = 0x0000;
3162
+  BG3VOFS  = 0x0000;
3163
+  BG2PA    = 0x0100;
3164
+  BG2PB    = 0x0000;
3165
+  BG2PC    = 0x0000;
3166
+  BG2PD    = 0x0100;
3167
+  BG2X_L   = 0x0000;
3168
+  BG2X_H   = 0x0000;
3169
+  BG2Y_L   = 0x0000;
3170
+  BG2Y_H   = 0x0000;
3171
+  BG3PA    = 0x0100;
3172
+  BG3PB    = 0x0000;
3173
+  BG3PC    = 0x0000;
3174
+  BG3PD    = 0x0100;
3175
+  BG3X_L   = 0x0000;
3176
+  BG3X_H   = 0x0000;
3177
+  BG3Y_L   = 0x0000;
3178
+  BG3Y_H   = 0x0000;
3179
+  WIN0H    = 0x0000;
3180
+  WIN1H    = 0x0000;
3181
+  WIN0V    = 0x0000;
3182
+  WIN1V    = 0x0000;
3183
+  WININ    = 0x0000;
3184
+  WINOUT   = 0x0000;
3185
+  MOSAIC   = 0x0000;
3186
+  BLDMOD   = 0x0000;
3187
+  COLEV    = 0x0000;
3188
+  COLY     = 0x0000;
3189
+  DM0SAD_L = 0x0000;
3190
+  DM0SAD_H = 0x0000;
3191
+  DM0DAD_L = 0x0000;
3192
+  DM0DAD_H = 0x0000;
3193
+  DM0CNT_L = 0x0000;
3194
+  DM0CNT_H = 0x0000;
3195
+  DM1SAD_L = 0x0000;
3196
+  DM1SAD_H = 0x0000;
3197
+  DM1DAD_L = 0x0000;
3198
+  DM1DAD_H = 0x0000;
3199
+  DM1CNT_L = 0x0000;
3200
+  DM1CNT_H = 0x0000;
3201
+  DM2SAD_L = 0x0000;
3202
+  DM2SAD_H = 0x0000;
3203
+  DM2DAD_L = 0x0000;
3204
+  DM2DAD_H = 0x0000;
3205
+  DM2CNT_L = 0x0000;
3206
+  DM2CNT_H = 0x0000;
3207
+  DM3SAD_L = 0x0000;
3208
+  DM3SAD_H = 0x0000;
3209
+  DM3DAD_L = 0x0000;
3210
+  DM3DAD_H = 0x0000;
3211
+  DM3CNT_L = 0x0000;
3212
+  DM3CNT_H = 0x0000;
3213
+  TM0D     = 0x0000;
3214
+  TM0CNT   = 0x0000;
3215
+  TM1D     = 0x0000;
3216
+  TM1CNT   = 0x0000;
3217
+  TM2D     = 0x0000;
3218
+  TM2CNT   = 0x0000;
3219
+  TM3D     = 0x0000;
3220
+  TM3CNT   = 0x0000;
3221
+  P1       = 0x03FF;
3222
+  IE       = 0x0000;
3223
+  IF       = 0x0000;
3224
+  IME      = 0x0000;
3225
+
3226
+  armMode = 0x1F;
3227
+
3228
+  if(cpuIsMultiBoot) {
3229
+    reg[13].I = 0x03007F00;
3230
+    reg[15].I = 0x02000000;
3231
+    reg[16].I = 0x00000000;
3232
+    reg[R13_IRQ].I = 0x03007FA0;
3233
+    reg[R13_SVC].I = 0x03007FE0;
3234
+    armIrqEnable = true;
3235
+  } else {
3236
+    if(useBios && !skipBios) {
3237
+      reg[15].I = 0x00000000;
3238
+      armMode = 0x13;
3239
+      armIrqEnable = false;
3240
+    } else {
3241
+      reg[13].I = 0x03007F00;
3242
+      reg[15].I = 0x08000000;
3243
+      reg[16].I = 0x00000000;
3244
+      reg[R13_IRQ].I = 0x03007FA0;
3245
+      reg[R13_SVC].I = 0x03007FE0;
3246
+      armIrqEnable = true;
3247
+    }
3248
+  }
3249
+  armState = true;
3250
+  C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false;
3251
+  UPDATE_REG(0x00, DISPCNT);
3252
+  UPDATE_REG(0x06, VCOUNT);
3253
+  UPDATE_REG(0x20, BG2PA);
3254
+  UPDATE_REG(0x26, BG2PD);
3255
+  UPDATE_REG(0x30, BG3PA);
3256
+  UPDATE_REG(0x36, BG3PD);
3257
+  UPDATE_REG(0x130, P1);
3258
+  UPDATE_REG(0x88, 0x200);
3259
+
3260
+  // disable FIQ
3261
+  reg[16].I |= 0x40;
3262
+
3263
+  CPUUpdateCPSR();
3264
+
3265
+  armNextPC = reg[15].I;
3266
+  reg[15].I += 4;
3267
+
3268
+  // reset internal state
3269
+  holdState = false;
3270
+  holdType = 0;
3271
+
3272
+  biosProtected[0] = 0x00;
3273
+  biosProtected[1] = 0xf0;
3274
+  biosProtected[2] = 0x29;
3275
+  biosProtected[3] = 0xe1;
3276
+
3277
+  lcdTicks = (useBios && !skipBios) ? 1008 : 208;
3278
+  timer0On = false;
3279
+  timer0Ticks = 0;
3280
+  timer0Reload = 0;
3281
+  timer0ClockReload  = 0;
3282
+  timer1On = false;
3283
+  timer1Ticks = 0;
3284
+  timer1Reload = 0;
3285
+  timer1ClockReload  = 0;
3286
+  timer2On = false;
3287
+  timer2Ticks = 0;
3288
+  timer2Reload = 0;
3289
+  timer2ClockReload  = 0;
3290
+  timer3On = false;
3291
+  timer3Ticks = 0;
3292
+  timer3Reload = 0;
3293
+  timer3ClockReload  = 0;
3294
+  dma0Source = 0;
3295
+  dma0Dest = 0;
3296
+  dma1Source = 0;
3297
+  dma1Dest = 0;
3298
+  dma2Source = 0;
3299
+  dma2Dest = 0;
3300
+  dma3Source = 0;
3301
+  dma3Dest = 0;
3302
+  //cpuSaveGameFunc = flashSaveDecide;
3303
+  //renderLine = mode0RenderLine;
3304
+  fxOn = false;
3305
+  windowOn = false;
3306
+  frameCount = 0;
3307
+  saveType = 0;
3308
+  layerEnable = DISPCNT & layerSettings;
3309
+
3310
+  //CPUUpdateRenderBuffers(true);
3311
+
3312
+  for(int i = 0; i < 256; i++) {
3313
+    map[i].address = (u8 *)&dummyAddress;
3314
+    map[i].mask = 0;
3315
+  }
3316
+
3317
+  map[0].address = bios;
3318
+  map[0].mask = 0x3FFF;
3319
+  map[2].address = workRAM;
3320
+  map[2].mask = 0x3FFFF;
3321
+  map[3].address = internalRAM;
3322
+  map[3].mask = 0x7FFF;
3323
+  map[4].address = ioMem;
3324
+  map[4].mask = 0x3FF;
3325
+  map[5].address = paletteRAM;
3326
+  map[5].mask = 0x3FF;
3327
+  map[6].address = vram;
3328
+  map[6].mask = 0x1FFFF;
3329
+  map[7].address = oam;
3330
+  map[7].mask = 0x3FF;
3331
+  map[8].address = rom;
3332
+  map[8].mask = 0x1FFFFFF;
3333
+  map[9].address = rom;
3334
+  map[9].mask = 0x1FFFFFF;
3335
+  map[10].address = rom;
3336
+  map[10].mask = 0x1FFFFFF;
3337
+  map[12].address = rom;
3338
+  map[12].mask = 0x1FFFFFF;
3339
+  map[14].address = /*flashSaveMemory*/0;
3340
+  map[14].mask = 0xFFFF;
3341
+
3342
+  //eepromReset();
3343
+  //flashReset();
3344
+
3345
+  soundReset();
3346
+
3347
+  //CPUUpdateWindow0();
3348
+  //CPUUpdateWindow1();
3349
+
3350
+  // make sure registers are correctly initialized if not using BIOS
3351
+  if(!useBios) {
3352
+    if(cpuIsMultiBoot)
3353
+      BIOS_RegisterRamReset(0xfe);
3354
+    else
3355
+      BIOS_RegisterRamReset(0xff);
3356
+  } else {
3357
+    if(cpuIsMultiBoot)
3358
+      BIOS_RegisterRamReset(0xfe);
3359
+  }
3360
+
3361
+  /*switch(cpuSaveType) {
3362
+  case 0: // automatic
3363
+    cpuSramEnabled = true;
3364
+    cpuFlashEnabled = true;
3365
+    cpuEEPROMEnabled = true;
3366
+    cpuEEPROMSensorEnabled = false;
3367
+    saveType = gbaSaveType = 0;
3368
+    break;
3369
+  case 1: // EEPROM
3370
+    cpuSramEnabled = false;
3371
+    cpuFlashEnabled = false;
3372
+    cpuEEPROMEnabled = true;
3373
+    cpuEEPROMSensorEnabled = false;
3374
+    saveType = gbaSaveType = 3;
3375
+    // EEPROM usage is automatically detected
3376
+    break;
3377
+  case 2: // SRAM
3378
+    cpuSramEnabled = true;
3379
+    cpuFlashEnabled = false;
3380
+    cpuEEPROMEnabled = false;
3381
+    cpuEEPROMSensorEnabled = false;
3382
+    cpuSaveGameFunc = sramDelayedWrite; // to insure we detect the write
3383
+    saveType = gbaSaveType = 1;
3384
+    break;
3385
+  case 3: // FLASH
3386
+    cpuSramEnabled = false;
3387
+    cpuFlashEnabled = true;
3388
+    cpuEEPROMEnabled = false;
3389
+    cpuEEPROMSensorEnabled = false;
3390
+    cpuSaveGameFunc = flashDelayedWrite; // to insure we detect the write
3391
+    saveType = gbaSaveType = 2;
3392
+    break;
3393
+  case 4: // EEPROM+Sensor
3394
+    cpuSramEnabled = false;
3395
+    cpuFlashEnabled = false;
3396
+    cpuEEPROMEnabled = true;
3397
+    cpuEEPROMSensorEnabled = true;
3398
+    // EEPROM usage is automatically detected
3399
+    saveType = gbaSaveType = 3;
3400
+    break;
3401
+  case 5: // NONE
3402
+    cpuSramEnabled = false;
3403
+    cpuFlashEnabled = false;
3404
+    cpuEEPROMEnabled = false;
3405
+    cpuEEPROMSensorEnabled = false;
3406
+    // no save at all
3407
+    saveType = gbaSaveType = 5;
3408
+    break;
3409
+  }*/
3410
+
3411
+  ARM_PREFETCH;
3412
+
3413
+  //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
3414
+
3415
+  cpuDmaHack = false;
3416
+
3417
+  lastTime = /*systemGetClock()*/0;
3418
+
3419
+  SWITicks = 0;
3420
+}
3421
+
3422
+void CPUInterrupt()
3423
+{
3424
+  u32 PC = reg[15].I;
3425
+  bool savedState = armState;
3426
+  CPUSwitchMode(0x12, true, false);
3427
+  reg[14].I = PC;
3428
+  if(!savedState)
3429
+    reg[14].I += 2;
3430
+  reg[15].I = 0x18;
3431
+  armState = true;
3432
+  armIrqEnable = false;
3433
+
3434
+  armNextPC = reg[15].I;
3435
+  reg[15].I += 4;
3436
+  ARM_PREFETCH;
3437
+
3438
+  //  if(!holdState)
3439
+  biosProtected[0] = 0x02;
3440
+  biosProtected[1] = 0xc0;
3441
+  biosProtected[2] = 0x5e;
3442
+  biosProtected[3] = 0xe5;
3443
+}
3444
+
3445
+void CPULoop(int ticks)
3446
+{
3447
+  int clockTicks;
3448
+  int timerOverflow = 0;
3449
+  // variable used by the CPU core
3450
+  cpuTotalTicks = 0;
3451
+
3452
+  // shuffle2: what's the purpose?
3453
+  /*if(gba_link_enabled)
3454
+    cpuNextEvent = 1;*/
3455
+
3456
+  cpuBreakLoop = false;
3457
+  cpuNextEvent = CPUUpdateTicks();
3458
+  if(cpuNextEvent > ticks)
3459
+    cpuNextEvent = ticks;
3460
+
3461
+
3462
+  for(;;) {
3463
+#ifndef FINAL_VERSION
3464
+    if(systemDebug) {
3465
+      if(systemDebug >= 10 && !holdState) {
3466
+        CPUUpdateCPSR();
3467
+#ifdef BKPT_SUPPORT
3468
+		if (debugger_last)
3469
+		{
3470
+		winlog("R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
3471
+                 oldreg[0], oldreg[1], oldreg[2], oldreg[3], oldreg[4], oldreg[5],
3472
+                 oldreg[6], oldreg[7], oldreg[8], oldreg[9], oldreg[10], oldreg[11],
3473
+                 oldreg[12], oldreg[13], oldreg[14], oldreg[15], oldreg[16],
3474
+                 oldreg[17]);
3475
+		}
3476
+#endif
3477
+        winlog("R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
3478
+                 reg[0].I, reg[1].I, reg[2].I, reg[3].I, reg[4].I, reg[5].I,
3479
+                 reg[6].I, reg[7].I, reg[8].I, reg[9].I, reg[10].I, reg[11].I,
3480
+                 reg[12].I, reg[13].I, reg[14].I, reg[15].I, reg[16].I,
3481
+                 reg[17].I);
3482
+      } else if(!holdState) {
3483
+        winlog("PC=%08x\n", armNextPC);
3484
+      }
3485
+    }
3486
+#endif /* FINAL_VERSION */
3487
+
3488
+    if(!holdState && !SWITicks) {
3489
+      if(armState) {
3490
+        if (!armExecute())
3491
+          return;
3492
+      } else {
3493
+        if (!thumbExecute())
3494
+          return;
3495
+      }
3496
+      clockTicks = 0;
3497
+    } else
3498
+      clockTicks = CPUUpdateTicks();
3499
+
3500
+    cpuTotalTicks += clockTicks;
3501
+
3502
+
3503
+    if(cpuTotalTicks >= cpuNextEvent) {
3504
+      int remainingTicks = cpuTotalTicks - cpuNextEvent;
3505
+
3506
+      if (SWITicks)
3507
+      {
3508
+        SWITicks-=clockTicks;
3509
+        if (SWITicks<0)
3510
+          SWITicks = 0;
3511
+      }
3512
+
3513
+      clockTicks = cpuNextEvent;
3514
+      cpuTotalTicks = 0;
3515
+      cpuDmaHack = false;
3516
+
3517
+    updateLoop:
3518
+
3519
+      if (IRQTicks)
3520
+      {
3521
+          IRQTicks -= clockTicks;
3522
+        if (IRQTicks<0)
3523
+          IRQTicks = 0;
3524
+      }
3525
+
3526
+      lcdTicks -= clockTicks;
3527
+
3528
+
3529
+      if(lcdTicks <= 0) {
3530
+        if(DISPSTAT & 1) { // V-BLANK
3531
+          // if in V-Blank mode, keep computing...
3532
+          if(DISPSTAT & 2) {
3533
+            lcdTicks += 1008;
3534
+            VCOUNT++;
3535
+            UPDATE_REG(0x06, VCOUNT);
3536
+            DISPSTAT &= 0xFFFD;
3537
+            UPDATE_REG(0x04, DISPSTAT);
3538
+            CPUCompareVCOUNT();
3539
+          } else {
3540
+            lcdTicks += 224;
3541
+            DISPSTAT |= 2;
3542
+            UPDATE_REG(0x04, DISPSTAT);
3543
+            if(DISPSTAT & 16) {
3544
+              IF |= 2;
3545
+              UPDATE_REG(0x202, IF);
3546
+            }
3547
+          }
3548
+
3549
+          if(VCOUNT >= 228) { //Reaching last line
3550
+            DISPSTAT &= 0xFFFC;
3551
+            UPDATE_REG(0x04, DISPSTAT);
3552
+            VCOUNT = 0;
3553
+            UPDATE_REG(0x06, VCOUNT);
3554
+            CPUCompareVCOUNT();
3555
+          }
3556
+        } else {
3557
+          int framesToSkip = /*systemFrameSkip*/0;
3558
+          if(speedup)
3559
+            framesToSkip = 9; // try 6 FPS during speedup
3560
+
3561
+          if(DISPSTAT & 2) {
3562
+            // if in H-Blank, leave it and move to drawing mode
3563
+            VCOUNT++;
3564
+            UPDATE_REG(0x06, VCOUNT);
3565
+
3566
+            lcdTicks += 1008;
3567
+            DISPSTAT &= 0xFFFD;
3568
+            if(VCOUNT == 160) {
3569
+              count++;
3570
+              //systemFrame();
3571
+
3572
+              if((count % 10) == 0) {
3573
+                //system10Frames(60);
3574
+              }
3575
+              if(count == 60) {
3576
+                u32 time = /*systemGetClock()*/0;
3577
+                if(time != lastTime) {
3578
+                  u32 t = 100000/(time - lastTime);
3579
+                  //systemShowSpeed(t);
3580
+                } else
3581
+                  //systemShowSpeed(0);
3582
+                lastTime = time;
3583
+                count = 0;
3584
+              }
3585
+              u32 joy = 0;
3586
+              // update joystick information
3587
+              /*if(systemReadJoypads())
3588
+                // read default joystick
3589
+                joy = systemReadJoypad(-1);*/
3590
+              P1 = 0x03FF ^ (joy & 0x3FF);
3591
+              /*if(cpuEEPROMSensorEnabled)
3592
+                systemUpdateMotionSensor();*/
3593
+              UPDATE_REG(0x130, P1);
3594
+              u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132]));
3595
+              // this seems wrong, but there are cases where the game
3596
+              // can enter the stop state without requesting an IRQ from
3597
+              // the joypad.
3598
+              if((P1CNT & 0x4000) || stopState) {
3599
+                u16 p1 = (0x3FF ^ P1) & 0x3FF;
3600
+                if(P1CNT & 0x8000) {
3601
+                  if(p1 == (P1CNT & 0x3FF)) {
3602
+                    IF |= 0x1000;
3603
+                    UPDATE_REG(0x202, IF);
3604
+                  }
3605
+                } else {
3606
+                  if(p1 & P1CNT) {
3607
+                    IF |= 0x1000;
3608
+                    UPDATE_REG(0x202, IF);
3609
+                  }
3610
+                }
3611
+              }
3612
+
3613
+              u32 ext = (joy >> 10);
3614
+              // If no (m) code is enabled, apply the cheats at each LCDline
3615
+              /*if((cheatsEnabled) && (mastercode==0))
3616
+                remainingTicks += cheatsCheckKeys(P1^0x3FF, ext);*/
3617
+              speedup = (ext & 1) ? true : false;
3618
+              capture = (ext & 2) ? true : false;
3619
+
3620
+              if(capture && !capturePrevious) {
3621
+                captureNumber++;
3622
+                //systemScreenCapture(captureNumber);
3623
+              }
3624
+              capturePrevious = capture;
3625
+
3626
+              DISPSTAT |= 1;
3627
+              DISPSTAT &= 0xFFFD;
3628
+              UPDATE_REG(0x04, DISPSTAT);
3629
+              if(DISPSTAT & 0x0008) {
3630
+                IF |= 1;
3631
+                UPDATE_REG(0x202, IF);
3632
+              }
3633
+              CPUCheckDMA(1, 0x0f);
3634
+              if(frameCount >= framesToSkip) {
3635
+                //systemDrawScreen();
3636
+                frameCount = 0;
3637
+              } else
3638
+                frameCount++;
3639
+              /*if(systemPauseOnFrame())
3640
+                ticks = 0;*/
3641
+            }
3642
+
3643
+            UPDATE_REG(0x04, DISPSTAT);
3644
+            CPUCompareVCOUNT();
3645
+
3646
+          } else {
3647
+            if(frameCount >= framesToSkip)
3648
+            {
3649
+              /*(*renderLine)();
3650
+              switch(systemColorDepth) {
3651
+                case 16:
3652
+                {
3653
+                  u16 *dest = (u16 *)pix + 242 * (VCOUNT+1);
3654
+                  for(int x = 0; x < 240;) {
3655
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3656
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3657
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3658
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3659
+
3660
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3661
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3662
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3663
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3664
+
3665
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3666
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3667
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3668
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3669
+
3670
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3671
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3672
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3673
+                    *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
3674
+                  }
3675
+                  // for filters that read past the screen
3676
+                  *dest++ = 0;
3677
+                }
3678
+                break;
3679
+                case 24:
3680
+                {
3681
+                  u8 *dest = (u8 *)pix + 240 * VCOUNT * 3;
3682
+                  for(int x = 0; x < 240;) {
3683
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3684
+                    dest += 3;
3685
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3686
+                    dest += 3;
3687
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3688
+                    dest += 3;
3689
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3690
+                    dest += 3;
3691
+
3692
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3693
+                    dest += 3;
3694
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3695
+                    dest += 3;
3696
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3697
+                    dest += 3;
3698
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3699
+                    dest += 3;
3700
+
3701
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3702
+                    dest += 3;
3703
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3704
+                    dest += 3;
3705
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3706
+                    dest += 3;
3707
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3708
+                    dest += 3;
3709
+
3710
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3711
+                    dest += 3;
3712
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3713
+                    dest += 3;
3714
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3715
+                    dest += 3;
3716
+                    *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
3717
+                    dest += 3;
3718
+                  }
3719
+                }
3720
+                break;
3721
+                case 32:
3722
+                {
3723
+                  u32 *dest = (u32 *)pix + 241 * (VCOUNT+1);
3724
+                  for(int x = 0; x < 240; ) {
3725
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3726
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3727
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3728
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3729
+
3730
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3731
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3732
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3733
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3734
+
3735
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3736
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3737
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3738
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3739
+
3740
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3741
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3742
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3743
+                    *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
3744
+                  }
3745
+                }
3746
+                break;
3747
+              }*/
3748
+            }
3749
+            // entering H-Blank
3750
+            DISPSTAT |= 2;
3751
+            UPDATE_REG(0x04, DISPSTAT);
3752
+            lcdTicks += 224;
3753
+            CPUCheckDMA(2, 0x0f);
3754
+            if(DISPSTAT & 16) {
3755
+              IF |= 2;
3756
+              UPDATE_REG(0x202, IF);
3757
+            }
3758
+          }
3759
+        }
3760
+      }
3761
+
3762
+	    // we shouldn't be doing sound in stop state, but we loose synchronization
3763
+      // if sound is disabled, so in stop state, soundTick will just produce
3764
+      // mute sound
3765
+      soundTicks -= clockTicks;
3766
+      if(soundTicks <= 0) {
3767
+        psoundTickfn();
3768
+        soundTicks += SOUND_CLOCK_TICKS;
3769
+      }
3770
+
3771
+      if(!stopState) {
3772
+        if(timer0On) {
3773
+          timer0Ticks -= clockTicks;
3774
+          if(timer0Ticks <= 0) {
3775
+            timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload;
3776
+            timerOverflow |= 1;
3777
+            soundTimerOverflow(0);
3778
+            if(TM0CNT & 0x40) {
3779
+              IF |= 0x08;
3780
+              UPDATE_REG(0x202, IF);
3781
+            }
3782
+          }
3783
+          TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload);
3784
+          UPDATE_REG(0x100, TM0D);
3785
+        }
3786
+
3787
+        if(timer1On) {
3788
+          if(TM1CNT & 4) {
3789
+            if(timerOverflow & 1) {
3790
+              TM1D++;
3791
+              if(TM1D == 0) {
3792
+                TM1D += timer1Reload;
3793
+                timerOverflow |= 2;
3794
+                soundTimerOverflow(1);
3795
+                if(TM1CNT & 0x40) {
3796
+                  IF |= 0x10;
3797
+                  UPDATE_REG(0x202, IF);
3798
+                }
3799
+              }
3800
+              UPDATE_REG(0x104, TM1D);
3801
+            }
3802
+          } else {
3803
+            timer1Ticks -= clockTicks;
3804
+            if(timer1Ticks <= 0) {
3805
+              timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload;
3806
+              timerOverflow |= 2;
3807
+              soundTimerOverflow(1);
3808
+              if(TM1CNT & 0x40) {
3809
+                IF |= 0x10;
3810
+                UPDATE_REG(0x202, IF);
3811
+              }
3812
+            }
3813
+            TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload);
3814
+            UPDATE_REG(0x104, TM1D);
3815
+          }
3816
+        }
3817
+
3818
+        if(timer2On) {
3819
+          if(TM2CNT & 4) {
3820
+            if(timerOverflow & 2) {
3821
+              TM2D++;
3822
+              if(TM2D == 0) {
3823
+                TM2D += timer2Reload;
3824
+                timerOverflow |= 4;
3825
+                if(TM2CNT & 0x40) {
3826
+                  IF |= 0x20;
3827
+                  UPDATE_REG(0x202, IF);
3828
+                }
3829
+              }
3830
+              UPDATE_REG(0x108, TM2D);
3831
+            }
3832
+          } else {
3833
+            timer2Ticks -= clockTicks;
3834
+            if(timer2Ticks <= 0) {
3835
+              timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload;
3836
+              timerOverflow |= 4;
3837
+              if(TM2CNT & 0x40) {
3838
+                IF |= 0x20;
3839
+                UPDATE_REG(0x202, IF);
3840
+              }
3841
+            }
3842
+            TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload);
3843
+            UPDATE_REG(0x108, TM2D);
3844
+          }
3845
+        }
3846
+
3847
+        if(timer3On) {
3848
+          if(TM3CNT & 4) {
3849
+            if(timerOverflow & 4) {
3850
+              TM3D++;
3851
+              if(TM3D == 0) {
3852
+                TM3D += timer3Reload;
3853
+                if(TM3CNT & 0x40) {
3854
+                  IF |= 0x40;
3855
+                  UPDATE_REG(0x202, IF);
3856
+                }
3857
+              }
3858
+              UPDATE_REG(0x10C, TM3D);
3859
+            }
3860
+          } else {
3861
+              timer3Ticks -= clockTicks;
3862
+            if(timer3Ticks <= 0) {
3863
+              timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload;
3864
+              if(TM3CNT & 0x40) {
3865
+                IF |= 0x40;
3866
+                UPDATE_REG(0x202, IF);
3867
+              }
3868
+            }
3869
+            TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload);
3870
+            UPDATE_REG(0x10C, TM3D);
3871
+          }
3872
+        }
3873
+      }
3874
+
3875
+      timerOverflow = 0;
3876
+
3877
+
3878
+
3879
+#ifdef PROFILING
3880
+      profilingTicks -= clockTicks;
3881
+      if(profilingTicks <= 0) {
3882
+        profilingTicks += profilingTicksReload;
3883
+        if(profilSegment) {
3884
+	  profile_segment *seg = profilSegment;
3885
+	  do {
3886
+	    u16 *b = (u16 *)seg->sbuf;
3887
+	    int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale)/0x10000;
3888
+	    if(pc >= 0 && pc < seg->ssiz) {
3889
+            b[pc]++;
3890
+	      break;
3891
+          }
3892
+
3893
+	    seg = seg->next;
3894
+	  } while(seg);
3895
+        }
3896
+      }
3897
+#endif
3898
+
3899
+      ticks -= clockTicks;
3900
+
3901
+	  /*if (gba_joybus_enabled)
3902
+		  JoyBusUpdate(clockTicks);
3903
+
3904
+	  if (gba_link_enabled)
3905
+		  LinkUpdate(clockTicks);*/
3906
+
3907
+      cpuNextEvent = CPUUpdateTicks();
3908
+
3909
+      if(cpuDmaTicksToUpdate > 0) {
3910
+        if(cpuDmaTicksToUpdate > cpuNextEvent)
3911
+          clockTicks = cpuNextEvent;
3912
+        else
3913
+          clockTicks = cpuDmaTicksToUpdate;
3914
+        cpuDmaTicksToUpdate -= clockTicks;
3915
+        if(cpuDmaTicksToUpdate < 0)
3916
+          cpuDmaTicksToUpdate = 0;
3917
+        cpuDmaHack = true;
3918
+        goto updateLoop;
3919
+      }
3920
+
3921
+	  // shuffle2: what's the purpose?
3922
+	  /*if(gba_link_enabled)
3923
+  	       cpuNextEvent = 1;*/
3924
+
3925
+      if(IF && (IME & 1) && armIrqEnable) {
3926
+        int res = IF & IE;
3927
+        if(stopState)
3928
+          res &= 0x3080;
3929
+        if(res) {
3930
+          if (intState)
3931
+          {
3932
+            if (!IRQTicks)
3933
+            {
3934
+              CPUInterrupt();
3935
+              intState = false;
3936
+              holdState = false;
3937
+              stopState = false;
3938
+              holdType = 0;
3939
+            }
3940
+          }
3941
+          else
3942
+          {
3943
+            if (!holdState)
3944
+            {
3945
+              intState = true;
3946
+              IRQTicks=7;
3947
+              if (cpuNextEvent> IRQTicks)
3948
+                cpuNextEvent = IRQTicks;
3949
+            }
3950
+            else
3951
+            {
3952
+              CPUInterrupt();
3953
+              holdState = false;
3954
+              stopState = false;
3955
+              holdType = 0;
3956
+            }
3957
+          }
3958
+
3959
+          // Stops the SWI Ticks emulation if an IRQ is executed
3960
+          //(to avoid problems with nested IRQ/SWI)
3961
+          if (SWITicks)
3962
+            SWITicks = 0;
3963
+        }
3964
+      }
3965
+
3966
+      if(remainingTicks > 0) {
3967
+        if(remainingTicks > cpuNextEvent)
3968
+          clockTicks = cpuNextEvent;
3969
+        else
3970
+          clockTicks = remainingTicks;
3971
+        remainingTicks -= clockTicks;
3972
+        if(remainingTicks < 0)
3973
+          remainingTicks = 0;
3974
+        goto updateLoop;
3975
+      }
3976
+
3977
+      if (timerOnOffDelay)
3978
+          applyTimer();
3979
+
3980
+      if(cpuNextEvent > ticks)
3981
+        cpuNextEvent = ticks;
3982
+
3983
+      if(ticks <= 0 || cpuBreakLoop)
3984
+        break;
3985
+
3986
+    }
3987
+  }
3988
+}
3989
+
3990
+
3991
+
3992
+/*struct EmulatedSystem GBASystem = {
3993
+  // emuMain
3994
+  CPULoop,
3995
+  // emuReset
3996
+  CPUReset,
3997
+  // emuCleanUp
3998
+  CPUCleanUp,
3999
+  // emuReadBattery
4000
+  CPUReadBatteryFile,
4001
+  // emuWriteBattery
4002
+  CPUWriteBatteryFile,
4003
+  // emuReadState
4004
+  CPUReadState,
4005
+  // emuWriteState
4006
+  CPUWriteState,
4007
+  // emuReadMemState
4008
+  CPUReadMemState,
4009
+  // emuWriteMemState
4010
+  CPUWriteMemState,
4011
+  // emuWritePNG
4012
+  CPUWritePNGFile,
4013
+  // emuWriteBMP
4014
+  CPUWriteBMPFile,
4015
+  // emuUpdateCPSR
4016
+  CPUUpdateCPSR,
4017
+  // emuHasDebugger
4018
+  true,
4019
+  // emuCount
4020
+#ifdef FINAL_VERSION
4021
+  250000
4022
+#else
4023
+  5000
4024
+#endif
4025
+};*/