Browse code

update for C++17 compliance, update to latest 2sf, add WINE cross-compile makefiles

Adam Higerd authored on 2021/02/11 15:36:17
Showing 1 changed files
... ...
@@ -129,7 +129,7 @@ uint32_t MMU_struct::MMU_MASK[2][256] =
129 129
 		/* 3X*/	DUP16(0x00007FFF),
130 130
 		/* 4X*/	DUP16(0x00FFFFFF),
131 131
 		/* 5X*/	DUP16(0x000007FF),
132
-		/* 6X*/	DUP16(0x00FFFFFF),
132
+		/* 6X*/	DUP16(0x000FFFFF),
133 133
 		/* 7X*/	DUP16(0x000007FF),
134 134
 		/* 8X*/	DUP16(0x00000003),
135 135
 		/* 9X*/	DUP16(0x00000003),
... ...
@@ -147,10 +147,10 @@ uint32_t MMU_struct::MMU_MASK[2][256] =
147 147
 		/* 2X*/	DUP16(0x003FFFFF),
148 148
 		/* 3X*/	DUP8(0x00007FFF),
149 149
 				DUP8(0x0000FFFF),
150
-		/* 4X*/	DUP8(0x00FFFFFF),
150
+		/* 4X*/	DUP8(0x0000FFFF),
151 151
 				DUP8(0x0000FFFF),
152 152
 		/* 5X*/	DUP16(0x00000003),
153
-		/* 6X*/	DUP16(0x00FFFFFF),
153
+		/* 6X*/	DUP16(0x000FFFFF),
154 154
 		/* 7X*/	DUP16(0x00000003),
155 155
 		/* 8X*/	DUP16(0x00000003),
156 156
 		/* 9X*/	DUP16(0x00000003),
... ...
@@ -671,8 +671,8 @@ static inline void MMU_VRAMmapControl(uint8_t block, uint8_t VRAMBankCnt)
671 671
 	MMU_VRAMmapRefreshBank(VRAM_BANK_C);
672 672
 	MMU_VRAMmapRefreshBank(VRAM_BANK_D);
673 673
 
674
-	//printf(vramConfiguration.describe().c_str());
675
-	//printf("vram remapped at vcount=%d\n",nds.VCount);
674
+	//fprintf(stderr, vramConfiguration.describe().c_str());
675
+	//fprintf(stderr, "vram remapped at vcount=%d\n",nds.VCount);
676 676
 
677 677
 	// -------------------------------
678 678
 	// set up arm9 mirrorings
... ...
@@ -1065,7 +1065,7 @@ void FASTCALL MMU_writeToGCControl(int PROCNUM, uint32_t val)
1065 1065
 	T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1066 1066
 
1067 1067
 	// Launch DMA if start flag was set to "DS Cart"
1068
-	//printf("triggering card dma\n");
1068
+	//fprintf(stderr, "triggering card dma\n");
1069 1069
 	triggerDma(EDMAMode_Card);
1070 1070
 }
1071 1071
 
... ...
@@ -1185,7 +1185,7 @@ static inline uint16_t read_timer(int proc, int timerIndex)
1185 1185
 	int32_t diff = (nds.timerCycle[proc][timerIndex] - nds_timer) & 0xFFFFFFFF;
1186 1186
 	assert(diff >= 0);
1187 1187
 	if (diff < 0)
1188
-		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: TIME READ DIFF < 0 (%d) (%d) (%d)\n", diff, timerIndex, MMU.timerMODE[proc][timerIndex]);
1188
+		fprintf(stderr, "NEW EMULOOP BAD NEWS PLEASE REPORT: TIME READ DIFF < 0 (%d) (%d) (%d)\n", diff, timerIndex, MMU.timerMODE[proc][timerIndex]);
1189 1189
 
1190 1190
 	int32_t units = diff / (1 << MMU.timerMODE[proc][timerIndex]);
1191 1191
 	int32_t ret;
... ...
@@ -1195,7 +1195,7 @@ static inline uint16_t read_timer(int proc, int timerIndex)
1195 1195
 	// whichever instruction setup this counter should advance nds_timer (I think?) and the division should truncate down to 65535 immediately
1196 1196
 	else if (units > 65536)
1197 1197
 	{
1198
-		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: UNITS %d:%d = %d\n", proc, timerIndex, units);
1198
+		fprintf(stderr, "NEW EMULOOP BAD NEWS PLEASE REPORT: UNITS %d:%d = %d\n", proc, timerIndex, units);
1199 1199
 		ret = 0;
1200 1200
 	}
1201 1201
 	else
... ...
@@ -1251,7 +1251,7 @@ uint32_t TGXSTAT::read32()
1251 1251
 
1252 1252
 	ret |= (this->gxfifo_irq & 0x3) << 30; // user's irq flags
1253 1253
 
1254
-	//printf("vc=%03d Returning gxstat read: %08X\n",nds.VCount,ret);
1254
+	//fprintf(stderr, "vc=%03d Returning gxstat read: %08X\n",nds.VCount,ret);
1255 1255
 
1256 1256
 	return ret;
1257 1257
 }
... ...
@@ -1266,13 +1266,13 @@ void TGXSTAT::write32(uint32_t val)
1266 1266
 		//mtxStack[0].position = 0;
1267 1267
 		this->se = 0; // clear stack error flag
1268 1268
 	}
1269
-	//printf("gxstat write: %08X while gxfifo.size=%d\n",val,gxFIFO.size);
1269
+	//fprintf(stderr, "gxstat write: %08X while gxfifo.size=%d\n",val,gxFIFO.size);
1270 1270
 }
1271 1271
 
1272 1272
 // this could be inlined...
1273 1273
 void MMU_struct_new::write_dma(int proc, int size, uint32_t _adr, uint32_t val)
1274 1274
 {
1275
-	//printf("%08lld -- write_dma: %d %d %08X %08X\n",nds_timer,proc,size,_adr,val);
1275
+	//fprintf(stderr, "%08lld -- write_dma: %d %d %08X %08X\n",nds_timer,proc,size,_adr,val);
1276 1276
 	uint32_t adr = _adr - _REG_DMA_CONTROL_MIN;
1277 1277
 	uint32_t chan = adr / 12;
1278 1278
 	uint32_t regnum = (adr - chan * 12) >> 2;
... ...
@@ -1288,7 +1288,7 @@ uint32_t MMU_struct_new::read_dma(int proc, int size, uint32_t _adr)
1288 1288
 	uint32_t regnum = (adr - chan * 12) >> 2;
1289 1289
 
1290 1290
 	uint32_t temp = MMU_new.dma[proc][chan].regs[regnum]->read(size, adr);
1291
-	//printf("%08lld --  read_dma: %d %d %08X = %08X\n",nds_timer,proc,size,_adr,temp);
1291
+	//fprintf(stderr, "%08lld --  read_dma: %d %d %08X = %08X\n",nds_timer,proc,size,_adr,temp);
1292 1292
 
1293 1293
 	return temp;
1294 1294
 }
... ...
@@ -1305,7 +1305,7 @@ MMU_struct_new::MMU_struct_new()
1305 1305
 
1306 1306
 void DmaController::write32(uint32_t val)
1307 1307
 {
1308
-	//printf("dma %d,%d WRITE %08X\n",procnum,chan,val);
1308
+	//fprintf(stderr, "dma %d,%d WRITE %08X\n",procnum,chan,val);
1309 1309
 	this->wordcount = val & 0x1FFFFF;
1310 1310
 	uint8_t wasEnable = this->enable;
1311 1311
 	uint32_t valhi = val >> 16;
... ...
@@ -1332,7 +1332,7 @@ void DmaController::write32(uint32_t val)
1332 1332
 		this->daddr = this->daddr_user;
1333 1333
 	}
1334 1334
 
1335
-	//printf("dma %d,%d set to startmode %d with wordcount set to: %08X\n",procnum,chan,_startmode,wordcount);
1335
+	//fprintf(stderr, "dma %d,%d set to startmode %d with wordcount set to: %08X\n",procnum,chan,_startmode,wordcount);
1336 1336
 	// analyze enabling and startmode.
1337 1337
 	// note that we only do this if the dma was freshly enabled.
1338 1338
 	// we should probably also only be latching these other regs in that case too..
... ...
@@ -1463,7 +1463,7 @@ template<int PROCNUM> void DmaController::doCopy()
1463 1463
 	// need to figure out what to do about this
1464 1464
 	if (bogarted)
1465 1465
 	{
1466
-		printf("YOUR GAME IS BOGARTED!!! PLEASE REPORT!!!\n");
1466
+		fprintf(stderr, "YOUR GAME IS BOGARTED!!! PLEASE REPORT!!!\n");
1467 1467
 		assert(false);
1468 1468
 		return;
1469 1469
 	}
... ...
@@ -1580,7 +1580,7 @@ uint32_t DmaController::read32()
1580 1580
 	ret |= this->sar << 23;
1581 1581
 	ret |= this->dar << 21;
1582 1582
 	ret |= this->wordcount;
1583
-	//printf("dma %d,%d READ  %08X\n",procnum,chan,ret);
1583
+	//fprintf(stderr, "dma %d,%d READ  %08X\n",procnum,chan,ret);
1584 1584
 	return ret;
1585 1585
 }
1586 1586
 
... ...
@@ -1621,30 +1621,30 @@ void FASTCALL _MMU_ARM9_write08(uint32_t adr, uint8_t val)
1621 1621
 		switch (adr)
1622 1622
 		{
1623 1623
 			case REG_SQRTCNT:
1624
-				printf("ERROR 8bit SQRTCNT WRITE\n");
1624
+				fprintf(stderr, "ERROR 8bit SQRTCNT WRITE\n");
1625 1625
 				return;
1626 1626
 			case REG_SQRTCNT + 1:
1627
-				printf("ERROR 8bit SQRTCNT1 WRITE\n");
1627
+				fprintf(stderr, "ERROR 8bit SQRTCNT1 WRITE\n");
1628 1628
 				return;
1629 1629
 			case REG_SQRTCNT + 2:
1630
-				printf("ERROR 8bit SQRTCNT2 WRITE\n");
1630
+				fprintf(stderr, "ERROR 8bit SQRTCNT2 WRITE\n");
1631 1631
 				return;
1632 1632
 			case REG_SQRTCNT + 3:
1633
-				printf("ERROR 8bit SQRTCNT3 WRITE\n");
1633
+				fprintf(stderr, "ERROR 8bit SQRTCNT3 WRITE\n");
1634 1634
 				return;
1635 1635
 
1636 1636
 #if 1
1637 1637
 			case REG_DIVCNT:
1638
-				printf("ERROR 8bit DIVCNT WRITE\n");
1638
+				fprintf(stderr, "ERROR 8bit DIVCNT WRITE\n");
1639 1639
 				return;
1640 1640
 			case REG_DIVCNT + 1:
1641
-				printf("ERROR 8bit DIVCNT+1 WRITE\n");
1641
+				fprintf(stderr, "ERROR 8bit DIVCNT+1 WRITE\n");
1642 1642
 				return;
1643 1643
 			case REG_DIVCNT + 2:
1644
-				printf("ERROR 8bit DIVCNT+2 WRITE\n");
1644
+				fprintf(stderr, "ERROR 8bit DIVCNT+2 WRITE\n");
1645 1645
 				return;
1646 1646
 			case REG_DIVCNT + 3:
1647
-				printf("ERROR 8bit DIVCNT+3 WRITE\n");
1647
+				fprintf(stderr, "ERROR 8bit DIVCNT+3 WRITE\n");
1648 1648
 				return;
1649 1649
 #endif
1650 1650
 
... ...
@@ -1734,12 +1734,12 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
1734 1734
 			case REG_DIVNUMER:
1735 1735
 			case REG_DIVNUMER + 2:
1736 1736
 			case REG_DIVNUMER + 4:
1737
-				printf("DIV: 16 write NUMER %08X. PLEASE REPORT! \n", val);
1737
+				fprintf(stderr, "DIV: 16 write NUMER %08X. PLEASE REPORT! \n", val);
1738 1738
 				break;
1739 1739
 			case REG_DIVDENOM:
1740 1740
 			case REG_DIVDENOM + 2:
1741 1741
 			case REG_DIVDENOM + 4:
1742
-				printf("DIV: 16 write DENOM %08X. PLEASE REPORT! \n", val);
1742
+				fprintf(stderr, "DIV: 16 write DENOM %08X. PLEASE REPORT! \n", val);
1743 1743
 				break;
1744 1744
 #endif
1745 1745
 			case REG_SQRTCNT:
... ...
@@ -2024,10 +2024,10 @@ uint8_t FASTCALL _MMU_ARM9_read08(uint32_t adr)
2024 2024
 
2025 2025
 			// sqrtcnt isnt big enough for these to exist. but they'd probably return 0 so its ok
2026 2026
 			case REG_SQRTCNT + 2:
2027
-				printf("ERROR 8bit SQRTCNT+2 READ\n");
2027
+				fprintf(stderr, "ERROR 8bit SQRTCNT+2 READ\n");
2028 2028
 				return 0;
2029 2029
 			case REG_SQRTCNT + 3:
2030
-				printf("ERROR 8bit SQRTCNT+3 READ\n");
2030
+				fprintf(stderr, "ERROR 8bit SQRTCNT+3 READ\n");
2031 2031
 				return 0;
2032 2032
 
2033 2033
 			// Nostalgia's options menu requires that these work
... ...
@@ -2038,10 +2038,10 @@ uint8_t FASTCALL _MMU_ARM9_read08(uint32_t adr)
2038 2038
 
2039 2039
 			// divcnt isnt big enough for these to exist. but they'd probably return 0 so its ok
2040 2040
 			case REG_DIVCNT + 2:
2041
-				printf("ERROR 8bit DIVCNT+2 READ\n");
2041
+				fprintf(stderr, "ERROR 8bit DIVCNT+2 READ\n");
2042 2042
 				return 0;
2043 2043
 			case REG_DIVCNT + 3:
2044
-				printf("ERROR 8bit DIVCNT+3 READ\n");
2044
+				fprintf(stderr, "ERROR 8bit DIVCNT+3 READ\n");
2045 2045
 				return 0;
2046 2046
 		}
2047 2047
 	}
... ...
@@ -2077,14 +2077,14 @@ uint16_t FASTCALL _MMU_ARM9_read16(uint32_t adr)
2077 2077
 				return MMU_new.sqrt.read16();
2078 2078
 			// sqrtcnt isnt big enough for this to exist. but it'd probably return 0 so its ok
2079 2079
 			case REG_SQRTCNT + 2:
2080
-				printf("ERROR 16bit SQRTCNT+2 READ\n");
2080
+				fprintf(stderr, "ERROR 16bit SQRTCNT+2 READ\n");
2081 2081
 				return 0;
2082 2082
 
2083 2083
 			case REG_DIVCNT:
2084 2084
 				return MMU_new.div.read16();
2085 2085
 			// divcnt isnt big enough for this to exist. but it'd probably return 0 so its ok
2086 2086
 			case REG_DIVCNT + 2:
2087
-				printf("ERROR 16bit DIVCNT+2 READ\n");
2087
+				fprintf(stderr, "ERROR 16bit DIVCNT+2 READ\n");
2088 2088
 				return 0;
2089 2089
 
2090 2090
 			case REG_IME:
... ...
@@ -2255,7 +2255,7 @@ void FASTCALL _MMU_ARM7_write08(uint32_t adr, uint8_t val)
2255 2255
 				break;
2256 2256
 
2257 2257
 			case REG_HALTCNT:
2258
-				//printf("halt 0x%02X\n", val);
2258
+				//fprintf(stderr, "halt 0x%02X\n", val);
2259 2259
 				switch (val)
2260 2260
 				{
2261 2261
 					case 0xC0:
... ...
@@ -2310,11 +2310,11 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2310 2310
 			case REG_DISPA_VCOUNT:
2311 2311
 				if (nds.VCount >= 202 && nds.VCount <= 212)
2312 2312
 				{
2313
-					printf("VCOUNT set to %i (previous value %i)\n", val, nds.VCount);
2313
+					fprintf(stderr, "VCOUNT set to %i (previous value %i)\n", val, nds.VCount);
2314 2314
 					nds.VCount = val;
2315 2315
 				}
2316 2316
 				else
2317
-					printf("Attempt to set VCOUNT while not within 202-212 (%i), ignored\n", nds.VCount);
2317
+					fprintf(stderr, "Attempt to set VCOUNT while not within 202-212 (%i), ignored\n", nds.VCount);
2318 2318
 				return;
2319 2319
 
2320 2320
 			case REG_EXMEMCNT:
... ...
@@ -2379,7 +2379,7 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2379 2379
 								// our totally pathetic register handling, only the one thing we've wanted so far
2380 2380
 								if (MMU.powerMan_Reg[0] & PM_SYSTEM_PWR)
2381 2381
 								{
2382
-									printf("SYSTEM POWERED OFF VIA ARM7 SPI POWER DEVICE\n");
2382
+									fprintf(stderr, "SYSTEM POWERED OFF VIA ARM7 SPI POWER DEVICE\n");
2383 2383
 									execute = false;
2384 2384
 								}
2385 2385
 							}
... ...
@@ -2413,7 +2413,7 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2413 2413
 						}
2414 2414
 
2415 2415
 						int channel = (MMU.SPI_CMD & 0x70) >> 4;
2416
-						//printf("%08X\n",channel);
2416
+						//fprintf(stderr, "%08X\n",channel);
2417 2417
 						switch (channel)
2418 2418
 						{
2419 2419
 							case TSC_MEASURE_TEMP1:
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
... ...
@@ -174,14 +174,14 @@ uint32_t MMU_struct::MMU_MASK[2][256] =
174 174
 static const uint8_t VRAM_PAGE_UNMAPPED = 41;
175 175
 
176 176
 static const unsigned VRAM_LCDC_PAGES = 41;
177
-uint8_t vram_lcdc_map[VRAM_LCDC_PAGES];
177
+static uint8_t vram_lcdc_map[VRAM_LCDC_PAGES];
178 178
 
179 179
 // in the range of 0x06000000 - 0x06800000 in 16KB pages (the ARM9 vram mappable area)
180 180
 // this maps to 16KB pages in the LCDC buffer which is what will actually contain the data
181 181
 uint8_t vram_arm9_map[VRAM_ARM9_PAGES];
182 182
 
183 183
 // this chooses which banks are mapped in the 128K banks starting at 0x06000000 in ARM7
184
-uint8_t vram_arm7_map[2];
184
+static uint8_t vram_arm7_map[2];
185 185
 
186 186
 struct TVramBankInfo
187 187
 {
... ...
@@ -1444,9 +1444,6 @@ template<int PROCNUM> void DmaController::doCopy()
1444 1444
 			break;
1445 1445
 		case EDMADestinationUpdate_IncrementReload:
1446 1446
 			dstinc = sz;
1447
-			break;
1448
-		default:
1449
-			bogarted = true;
1450 1447
 	}
1451 1448
 	switch (this->sar)
1452 1449
 	{
... ...
@@ -1460,7 +1457,6 @@ template<int PROCNUM> void DmaController::doCopy()
1460 1457
 			srcinc = 0;
1461 1458
 			break;
1462 1459
 		case EDMASourceUpdate_Invalid:
1463
-		default:
1464 1460
 			bogarted = true;
1465 1461
 	}
1466 1462
 
Browse code

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

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

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -433,7 +433,7 @@ static inline void MMU_VRAMmapRefreshBank(int bank)
433 433
 					MMU.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
434 434
 					break;
435 435
 				case 4: // BGB or BOBJ
436
-					if (bank == VRAM_BANK_C) 
436
+					if (bank == VRAM_BANK_C)
437 437
 					{
438 438
 						vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
439 439
 						MMU_vram_arm9(bank, VRAM_PAGE_BBG); // BBG
... ...
@@ -604,7 +604,7 @@ void MMU_VRAM_unmap_all()
604 604
 	vram_arm7_map[0] = VRAM_PAGE_UNMAPPED;
605 605
 	vram_arm7_map[1] = VRAM_PAGE_UNMAPPED;
606 606
 
607
-	for (int i = 0; i < VRAM_LCDC_PAGES; ++i)
607
+	for (unsigned i = 0; i < VRAM_LCDC_PAGES; ++i)
608 608
 		vram_lcdc_map[i] = VRAM_PAGE_UNMAPPED;
609 609
 	for (int i = 0; i < VRAM_ARM9_PAGES; ++i)
610 610
 		vram_arm9_map[i] = VRAM_PAGE_UNMAPPED;
... ...
@@ -636,8 +636,8 @@ static inline void MMU_VRAMmapControl(uint8_t block, uint8_t VRAMBankCnt)
636 636
 		return;
637 637
 	}
638 638
 
639
-	//f irst, save the texture info so we can check it for changes and trigger purges of the texcache
640
-	MMU_struct::TextureInfo oldTexInfo = MMU.texInfo;
639
+	// first, save the texture info so we can check it for changes and trigger purges of the texcache
640
+	//MMU_struct::TextureInfo oldTexInfo = MMU.texInfo;
641 641
 
642 642
 	// unmap everything
643 643
 	MMU_VRAM_unmap_all();
... ...
@@ -664,7 +664,7 @@ static inline void MMU_VRAMmapControl(uint8_t block, uint8_t VRAMBankCnt)
664 664
 	MMU_VRAMmapRefreshBank(VRAM_BANK_E);
665 665
 	// zero 21-jun-2012
666 666
 	// tomwi's streaming music demo sets A and D to ABG (the A is an accident).
667
-	// in this case, D should get priority. 
667
+	// in this case, D should get priority.
668 668
 	// this is somewhat risky. will it break other things?
669 669
 	MMU_VRAMmapRefreshBank(VRAM_BANK_A);
670 670
 	MMU_VRAMmapRefreshBank(VRAM_BANK_B);
... ...
@@ -1392,6 +1392,9 @@ void DmaController::exec()
1392 1392
 		{
1393 1393
 			case EDMAMode_Immediate:
1394 1394
 				this->triggered = true;
1395
+				break;
1396
+			default:
1397
+				break;
1395 1398
 		}
1396 1399
 
1397 1400
 		if (this->triggered)
... ...
@@ -2244,7 +2247,7 @@ void FASTCALL _MMU_ARM7_write08(uint32_t adr, uint8_t val)
2244 2247
 				// The NDS7 register can be written to only from code executed in BIOS.
2245 2248
 				if (NDS_ARM7.instruct_adr > 0x3FFF)
2246 2249
 					return;
2247
-				
2250
+
2248 2251
 				// hack for patched firmwares
2249 2252
 				if (val == 1)
2250 2253
 				{
Browse code

[2SF] Minor template removal.

Naram Qashat authored on 2014/09/08 13:53:30
Showing 1 changed files
... ...
@@ -214,7 +214,7 @@ static const uint32_t ARM7_HACKY_SIWRAM_LOCATION = 0x03000000;
214 214
 // NOTE - this whole approach is probably fundamentally wrong.
215 215
 // according to dasShiny research, its possible to map multiple banks to the same addresses. something more sophisticated would be needed.
216 216
 // however, it hasnt proven necessary yet for any known test case.
217
-template<int PROCNUM> static inline uint32_t MMU_LCDmap(uint32_t addr, bool &unmapped, bool &restricted)
217
+static inline uint32_t MMU_LCDmap(int PROCNUM, uint32_t addr, bool &unmapped, bool &restricted)
218 218
 {
219 219
 	unmapped = false;
220 220
 	restricted = false; // this will track whether 8bit writes are allowed
... ...
@@ -988,7 +988,7 @@ uint16_t DSI_TSC::read16()
988 988
 
989 989
 // TODO:
990 990
 // NAND flash support (used in Made in Ore/WarioWare D.I.Y.)
991
-template<int PROCNUM> void FASTCALL MMU_writeToGCControl(uint32_t val)
991
+void FASTCALL MMU_writeToGCControl(int PROCNUM, uint32_t val)
992 992
 {
993 993
 	int TEST_PROCNUM = PROCNUM;
994 994
 	nds_dscard &card = MMU.dscard[TEST_PROCNUM];
... ...
@@ -1069,7 +1069,7 @@ template<int PROCNUM> void FASTCALL MMU_writeToGCControl(uint32_t val)
1069 1069
 	triggerDma(EDMAMode_Card);
1070 1070
 }
1071 1071
 
1072
-template<int PROCNUM> uint32_t MMU_readFromGC()
1072
+uint32_t MMU_readFromGC(int PROCNUM)
1073 1073
 {
1074 1074
 	int TEST_PROCNUM = PROCNUM;
1075 1075
 
... ...
@@ -1109,7 +1109,7 @@ template<int PROCNUM> uint32_t MMU_readFromGC()
1109 1109
 	return val;
1110 1110
 }
1111 1111
 
1112
-template<int PROCNUM> static void REG_IF_WriteByte(uint32_t addr, uint8_t val)
1112
+static void REG_IF_WriteByte(int PROCNUM, uint32_t addr, uint8_t val)
1113 1113
 {
1114 1114
 	// the following bits are generated from logic and should not be affected here
1115 1115
 	// Bit 21    NDS9 only: Geometry Command FIFO
... ...
@@ -1132,18 +1132,18 @@ template<int PROCNUM> static void REG_IF_WriteByte(uint32_t addr, uint8_t val)
1132 1132
 	NDS_Reschedule();
1133 1133
 }
1134 1134
 
1135
-template<int PROCNUM> static void REG_IF_WriteWord(uint32_t addr, uint16_t val)
1135
+static void REG_IF_WriteWord(int PROCNUM, uint32_t addr, uint16_t val)
1136 1136
 {
1137
-	REG_IF_WriteByte<PROCNUM>(addr, val & 0xFF);
1138
-	REG_IF_WriteByte<PROCNUM>(addr + 1, (val >> 8) & 0xFF);
1137
+	REG_IF_WriteByte(PROCNUM, addr, val & 0xFF);
1138
+	REG_IF_WriteByte(PROCNUM, addr + 1, (val >> 8) & 0xFF);
1139 1139
 }
1140 1140
 
1141
-template<int PROCNUM> static void REG_IF_WriteLong(uint32_t val)
1141
+static void REG_IF_WriteLong(int PROCNUM, uint32_t val)
1142 1142
 {
1143
-	REG_IF_WriteByte<PROCNUM>(0, val & 0xFF);
1144
-	REG_IF_WriteByte<PROCNUM>(1, (val >> 8) & 0xFF);
1145
-	REG_IF_WriteByte<PROCNUM>(2, (val >> 16) & 0xFF);
1146
-	REG_IF_WriteByte<PROCNUM>(3, (val >> 24) & 0xFF);
1143
+	REG_IF_WriteByte(PROCNUM, 0, val & 0xFF);
1144
+	REG_IF_WriteByte(PROCNUM, 1, (val >> 8) & 0xFF);
1145
+	REG_IF_WriteByte(PROCNUM, 2, (val >> 16) & 0xFF);
1146
+	REG_IF_WriteByte(PROCNUM, 3, (val >> 24) & 0xFF);
1147 1147
 }
1148 1148
 
1149 1149
 template<int PROCNUM> uint32_t MMU_struct::gen_IF()
... ...
@@ -1650,16 +1650,16 @@ void FASTCALL _MMU_ARM9_write08(uint32_t adr, uint8_t val)
1650 1650
 #endif
1651 1651
 
1652 1652
 			case REG_IF:
1653
-				REG_IF_WriteByte<ARMCPU_ARM9>(0, val);
1653
+				REG_IF_WriteByte(ARMCPU_ARM9, 0, val);
1654 1654
 				break;
1655 1655
 			case REG_IF + 1:
1656
-				REG_IF_WriteByte<ARMCPU_ARM9>(1, val);
1656
+				REG_IF_WriteByte(ARMCPU_ARM9, 1, val);
1657 1657
 				break;
1658 1658
 			case REG_IF + 2:
1659
-				REG_IF_WriteByte<ARMCPU_ARM9>(2, val);
1659
+				REG_IF_WriteByte(ARMCPU_ARM9, 2, val);
1660 1660
 				break;
1661 1661
 			case REG_IF + 3:
1662
-				REG_IF_WriteByte<ARMCPU_ARM9>(3, val);
1662
+				REG_IF_WriteByte(ARMCPU_ARM9, 3, val);
1663 1663
 				break;
1664 1664
 
1665 1665
 			case REG_VRAMCNTA:
... ...
@@ -1779,10 +1779,11 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
1779 1779
 				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9] & 0xFFFF) | (val << 16);
1780 1780
 				return;
1781 1781
 			case REG_IF:
1782
-				REG_IF_WriteWord<ARMCPU_ARM9>(0, val);
1782
+				REG_IF_WriteWord(ARMCPU_ARM9, 0, val);
1783
+				return;
1784
+			case REG_IF + 2:
1785
+				REG_IF_WriteWord(ARMCPU_ARM9, 2, val);
1783 1786
 				return;
1784
-			case REG_IF+2:
1785
-				REG_IF_WriteWord<ARMCPU_ARM9>(2, val); return;
1786 1787
 
1787 1788
 			case REG_IPCSYNC:
1788 1789
 				MMU_IPCSync(ARMCPU_ARM9, val);
... ...
@@ -1808,10 +1809,10 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
1808 1809
 			}
1809 1810
 
1810 1811
 			case REG_GCROMCTRL:
1811
-				MMU_writeToGCControl<ARMCPU_ARM9>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF0000) | val);
1812
+				MMU_writeToGCControl(ARMCPU_ARM9, (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF0000) | val);
1812 1813
 				return;
1813 1814
 			case REG_GCROMCTRL + 2:
1814
-				MMU_writeToGCControl<ARMCPU_ARM9>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF) | (val << 16));
1815
+				MMU_writeToGCControl(ARMCPU_ARM9, (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF) | (val << 16));
1815 1816
 				return;
1816 1817
 		}
1817 1818
 
... ...
@@ -1820,7 +1821,7 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
1820 1821
 	}
1821 1822
 
1822 1823
 	bool unmapped, restricted;
1823
-	adr = MMU_LCDmap<ARMCPU_ARM9>(adr, unmapped, restricted);
1824
+	adr = MMU_LCDmap(ARMCPU_ARM9, adr, unmapped, restricted);
1824 1825
 	if (unmapped)
1825 1826
 		return;
1826 1827
 
... ...
@@ -1892,7 +1893,7 @@ void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
1892 1893
 				return;
1893 1894
 
1894 1895
 			case REG_IF:
1895
-				REG_IF_WriteLong<ARMCPU_ARM9>(val);
1896
+				REG_IF_WriteLong(ARMCPU_ARM9, val);
1896 1897
 				return;
1897 1898
 
1898 1899
 			case REG_TM0CNTL:
... ...
@@ -1953,7 +1954,7 @@ void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
1953 1954
 				return;
1954 1955
 
1955 1956
 			case REG_GCROMCTRL:
1956
-				MMU_writeToGCControl<ARMCPU_ARM9>(val);
1957
+				MMU_writeToGCControl(ARMCPU_ARM9, val);
1957 1958
 				return;
1958 1959
 			case REG_DISPA_DISPCAPCNT:
1959 1960
 				T1WriteLong(MMU.ARM9_REG, 0x64, val);
... ...
@@ -1969,7 +1970,7 @@ void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
1969 1970
 	}
1970 1971
 
1971 1972
 	bool unmapped, restricted;
1972
-	adr = MMU_LCDmap<ARMCPU_ARM9>(adr, unmapped, restricted);
1973
+	adr = MMU_LCDmap(ARMCPU_ARM9, adr, unmapped, restricted);
1973 1974
 	if (unmapped)
1974 1975
 		return;
1975 1976
 
... ...
@@ -2047,7 +2048,7 @@ uint8_t FASTCALL _MMU_ARM9_read08(uint32_t adr)
2047 2048
 	}
2048 2049
 
2049 2050
 	bool unmapped, restricted;
2050
-	adr = MMU_LCDmap<ARMCPU_ARM9>(adr, unmapped, restricted);
2051
+	adr = MMU_LCDmap(ARMCPU_ARM9, adr, unmapped, restricted);
2051 2052
 	if (unmapped)
2052 2053
 		return 0;
2053 2054
 
... ...
@@ -2181,7 +2182,7 @@ uint32_t FASTCALL _MMU_ARM9_read32(uint32_t adr)
2181 2182
 			}
2182 2183
 
2183 2184
 			case REG_GCDATAIN:
2184
-				return MMU_readFromGC<ARMCPU_ARM9>();
2185
+				return MMU_readFromGC(ARMCPU_ARM9);
2185 2186
 		}
2186 2187
 		return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]);
2187 2188
 	}
... ...
@@ -2227,16 +2228,16 @@ void FASTCALL _MMU_ARM7_write08(uint32_t adr, uint8_t val)
2227 2228
 		switch (adr)
2228 2229
 		{
2229 2230
 			case REG_IF:
2230
-				REG_IF_WriteByte<ARMCPU_ARM7>(0, val);
2231
+				REG_IF_WriteByte(ARMCPU_ARM7, 0, val);
2231 2232
 				break;
2232 2233
 			case REG_IF + 1:
2233
-				REG_IF_WriteByte<ARMCPU_ARM7>(1, val);
2234
+				REG_IF_WriteByte(ARMCPU_ARM7, 1, val);
2234 2235
 				break;
2235 2236
 			case REG_IF + 2:
2236
-				REG_IF_WriteByte<ARMCPU_ARM7>(2, val);
2237
+				REG_IF_WriteByte(ARMCPU_ARM7, 2, val);
2237 2238
 				break;
2238 2239
 			case REG_IF + 3:
2239
-				REG_IF_WriteByte<ARMCPU_ARM7>(3, val);
2240
+				REG_IF_WriteByte(ARMCPU_ARM7, 3, val);
2240 2241
 				break;
2241 2242
 
2242 2243
 			case REG_POSTFLG:
... ...
@@ -2530,10 +2531,10 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2530 2531
 				return;
2531 2532
 
2532 2533
 			case REG_IF:
2533
-				REG_IF_WriteWord<ARMCPU_ARM7>(0, val);
2534
+				REG_IF_WriteWord(ARMCPU_ARM7, 0, val);
2534 2535
 				return;
2535 2536
 			case REG_IF + 2:
2536
-				REG_IF_WriteWord<ARMCPU_ARM7>(2, val);
2537
+				REG_IF_WriteWord(ARMCPU_ARM7, 2, val);
2537 2538
 				return;
2538 2539
 
2539 2540
 			case REG_IPCSYNC:
... ...
@@ -2560,10 +2561,10 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2560 2561
 			}
2561 2562
 
2562 2563
 			case REG_GCROMCTRL:
2563
-				MMU_writeToGCControl<ARMCPU_ARM7>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF0000) | val);
2564
+				MMU_writeToGCControl(ARMCPU_ARM7, (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF0000) | val);
2564 2565
 				return;
2565 2566
 			case REG_GCROMCTRL + 2:
2566
-				MMU_writeToGCControl<ARMCPU_ARM7>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF) | (val << 16));
2567
+				MMU_writeToGCControl(ARMCPU_ARM7, (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF) | (val << 16));
2567 2568
 				return;
2568 2569
 		}
2569 2570
 
... ...
@@ -2619,7 +2620,7 @@ void FASTCALL _MMU_ARM7_write32(uint32_t adr, uint32_t val)
2619 2620
 				return;
2620 2621
 
2621 2622
 			case REG_IF:
2622
-				REG_IF_WriteLong<ARMCPU_ARM7>(val);
2623
+				REG_IF_WriteLong(ARMCPU_ARM7, val);
2623 2624
 				return;
2624 2625
 
2625 2626
 			case REG_TM0CNTL:
... ...
@@ -2645,7 +2646,7 @@ void FASTCALL _MMU_ARM7_write32(uint32_t adr, uint32_t val)
2645 2646
 				return;
2646 2647
 
2647 2648
 			case REG_GCROMCTRL:
2648
-				MMU_writeToGCControl<ARMCPU_ARM7>(val);
2649
+				MMU_writeToGCControl(ARMCPU_ARM7, val);
2649 2650
 				return;
2650 2651
 
2651 2652
 			case REG_GCDATAIN:
... ...
@@ -2818,7 +2819,7 @@ uint32_t FASTCALL _MMU_ARM7_read32(uint32_t adr)
2818 2819
 			case REG_GCROMCTRL:
2819 2820
 				break;
2820 2821
 			case REG_GCDATAIN:
2821
-				return MMU_readFromGC<ARMCPU_ARM7>();
2822
+				return MMU_readFromGC(ARMCPU_ARM7);
2822 2823
 
2823 2824
 			case REG_VRAMSTAT:
2824 2825
 				// make sure WRAMSTAT is stashed and then fallthrough return the value from memory. i know, gross.
Browse code

Removed a bunch of casts, they seem to be fine without them in most cases.

Naram Qashat authored on 2013/04/18 23:22:54
Showing 1 changed files
... ...
@@ -41,7 +41,7 @@ static uint64_t isqrt(uint64_t x)
41 41
 	 * is even, and the one bit is as far left as is consistant
42 42
 	 * with that condition.)
43 43
 	 */
44
-	uint64_t squaredbit = static_cast<uint64_t>((static_cast<uint64_t>(~0LL) >> 1) & ~(static_cast<uint64_t>(~0LL) >> 2));
44
+	uint64_t squaredbit = (~0LL >> 1) & ~(~0LL >> 2);
45 45
 	/* This portable load replaces the loop that used to be
46 46
 	 * here, and was donated by  legalize@xmission.com
47 47
 	 */
... ...
@@ -860,12 +860,12 @@ static void execsqrt()
860 860
 	if (mode)
861 861
 	{
862 862
 		uint64_t v = T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B8);
863
-		ret = static_cast<uint32_t>(isqrt(v));
863
+		ret = isqrt(v) & 0xFFFFFFFF;
864 864
 	}
865 865
 	else
866 866
 	{
867 867
 		uint32_t v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B8);
868
-		ret = static_cast<uint32_t>(isqrt(v));
868
+		ret = isqrt(v) & 0xFFFFFFFF;
869 869
 	}
870 870
 
871 871
 	// clear the result while the sqrt unit is busy
... ...
@@ -889,20 +889,20 @@ static void execdiv()
889 889
 	switch (mode)
890 890
 	{
891 891
 		case 0: // 32/32
892
-			num = static_cast<int64_t>(static_cast<int32_t>(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290)));
893
-			den = static_cast<int64_t>(static_cast<int32_t>(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298)));
892
+			num = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
893
+			den = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
894 894
 			MMU.divCycles = nds_timer + 36;
895 895
 			break;
896 896
 		case 1: // 64/32
897
-		case 3: //gbatek says this is same as mode 1
898
-			num = static_cast<int64_t>(T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290));
899
-			den = static_cast<int64_t>(static_cast<int32_t>(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298)));
897
+		case 3: // gbatek says this is same as mode 1
898
+			num = T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
899
+			den = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
900 900
 			MMU.divCycles = nds_timer + 68;
901 901
 			break;
902 902
 		case 2: // 64/64
903 903
 		default:
904
-			num = static_cast<int64_t>(T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290));
905
-			den = static_cast<int64_t>(T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298));
904
+			num = T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
905
+			den = T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
906 906
 			MMU.divCycles = nds_timer + 68;
907 907
 	}
908 908
 
... ...
@@ -912,7 +912,7 @@ static void execdiv()
912 912
 		mod = num;
913 913
 
914 914
 		// the DIV0 flag in DIVCNT is set only if the full 64bit DIV_DENOM value is zero, even in 32bit mode
915
-		if (!static_cast<uint64_t>(T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298)))
915
+		if (!T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298))
916 916
 			MMU_new.div.div0 = 1;
917 917
 	}
918 918
 	else
... ...
@@ -958,7 +958,7 @@ uint16_t DSI_TSC::write16(uint16_t val)
958 958
 			return this->read16();
959 959
 		case 1:
960 960
 			if (!this->read_flag)
961
-				this->registers[this->reg_selection] = static_cast<uint8_t>(val);
961
+				this->registers[this->reg_selection] = val & 0xFF;
962 962
 			ret = this->read16();
963 963
 			++this->reg_selection;
964 964
 			this->reg_selection &= 0x7F;
... ...
@@ -1128,7 +1128,7 @@ template<int PROCNUM> static void REG_IF_WriteByte(uint32_t addr, uint8_t val)
1128 1128
 	// ZERO 01-dec-2010 : I am no longer sure this approach is correct.. it proved to be wrong for IPC fifo.......
1129 1129
 	// it seems as if IF bits should always be cached (only the user can clear them)
1130 1130
 
1131
-	MMU.reg_IF_bits[PROCNUM] &= ~(static_cast<uint32_t>(val) << (addr << 3));
1131
+	MMU.reg_IF_bits[PROCNUM] &= ~(val << (addr << 3));
1132 1132
 	NDS_Reschedule();
1133 1133
 }
1134 1134
 
... ...
@@ -1182,7 +1182,7 @@ static inline uint16_t read_timer(int proc, int timerIndex)
1182 1182
 		return MMU.timer[proc][timerIndex];
1183 1183
 
1184 1184
 	// for unchained timers, we do not keep the timer up to date. its value will need to be calculated here
1185
-	int32_t diff = static_cast<int32_t>(nds.timerCycle[proc][timerIndex] - nds_timer);
1185
+	int32_t diff = (nds.timerCycle[proc][timerIndex] - nds_timer) & 0xFFFFFFFF;
1186 1186
 	assert(diff >= 0);
1187 1187
 	if (diff < 0)
1188 1188
 		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: TIME READ DIFF < 0 (%d) (%d) (%d)\n", diff, timerIndex, MMU.timerMODE[proc][timerIndex]);
... ...
@@ -1201,7 +1201,7 @@ static inline uint16_t read_timer(int proc, int timerIndex)
1201 1201
 	else
1202 1202
 		ret = 65535 - units;
1203 1203
 
1204
-	return static_cast<uint16_t>(ret);
1204
+	return ret & 0xFFFF;
1205 1205
 }
1206 1206
 
1207 1207
 static inline void write_timer(int proc, int timerIndex, uint16_t val)
... ...
@@ -1311,13 +1311,13 @@ void DmaController::write32(uint32_t val)
1311 1311
 	uint32_t valhi = val >> 16;
1312 1312
 	this->dar = static_cast<EDMADestinationUpdate>((valhi >> 5) & 3);
1313 1313
 	this->sar = static_cast<EDMASourceUpdate>((valhi >> 7) & 3);
1314
-	this->repeatMode = static_cast<uint8_t>(BIT9(valhi));
1314
+	this->repeatMode = BIT9(valhi);
1315 1315
 	this->bitWidth = static_cast<EDMABitWidth>(BIT10(valhi));
1316 1316
 	this->_startmode = (valhi >> 11) & 7;
1317 1317
 	if (this->procnum == ARMCPU_ARM7)
1318 1318
 		this->_startmode &= 6;
1319
-	this->irq = static_cast<uint8_t>(BIT14(valhi));
1320
-	this->enable = static_cast<uint8_t>(BIT15(valhi));
1319
+	this->irq = BIT14(valhi);
1320
+	this->enable = BIT15(valhi);
1321 1321
 
1322 1322
 	// make sure we don't get any old triggers
1323 1323
 	if (!wasEnable && this->enable)
... ...
@@ -1434,7 +1434,7 @@ template<int PROCNUM> void DmaController::doCopy()
1434 1434
 			dstinc = sz;
1435 1435
 			break;
1436 1436
 		case EDMADestinationUpdate_Decrement:
1437
-			dstinc = static_cast<uint32_t>(-static_cast<int32_t>(sz));
1437
+			dstinc = -static_cast<int32_t>(sz);
1438 1438
 			break;
1439 1439
 		case EDMADestinationUpdate_Fixed:
1440 1440
 			dstinc = 0;
... ...
@@ -1451,7 +1451,7 @@ template<int PROCNUM> void DmaController::doCopy()
1451 1451
 			srcinc = sz;
1452 1452
 			break;
1453 1453
 		case EDMASourceUpdate_Decrement:
1454
-			srcinc = static_cast<uint32_t>(-static_cast<int32_t>(sz));
1454
+			srcinc = -static_cast<int32_t>(sz);
1455 1455
 			break;
1456 1456
 		case EDMASourceUpdate_Fixed:
1457 1457
 			srcinc = 0;
... ...
@@ -1479,7 +1479,7 @@ template<int PROCNUM> void DmaController::doCopy()
1479 1479
 	// we might make another function to do just the raw copy op which can use them with checks
1480 1480
 	// outside the loop
1481 1481
 	int time_elapsed = 0;
1482
-	for (int32_t i = static_cast<int32_t>(todo); i > 0; --i)
1482
+	for (int32_t i = todo; i > 0; --i)
1483 1483
 	{
1484 1484
 		if (sz == 4)
1485 1485
 		{
... ...
@@ -1672,7 +1672,7 @@ void FASTCALL _MMU_ARM9_write08(uint32_t adr, uint8_t val)
1672 1672
 			case REG_WRAMCNT:
1673 1673
 			case REG_VRAMCNTH:
1674 1674
 			case REG_VRAMCNTI:
1675
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA), val);
1675
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA, val);
1676 1676
 		}
1677 1677
 
1678 1678
 		MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20][adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]] = val;
... ...
@@ -1761,8 +1761,8 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
1761 1761
 			case REG_VRAMCNTE:
1762 1762
 			case REG_VRAMCNTG:
1763 1763
 			case REG_VRAMCNTH:
1764
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA), val & 0xFF);
1765
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 1), val >> 8);
1764
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA, val & 0xFF);
1765
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA + 1, val >> 8);
1766 1766
 				break;
1767 1767
 
1768 1768
 			case REG_IME:
... ...
@@ -1776,7 +1776,7 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
1776 1776
 				return;
1777 1777
 			case REG_IE + 2:
1778 1778
 				NDS_Reschedule();
1779
-				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9] & 0xFFFF) | (static_cast<uint32_t>(val) << 16);
1779
+				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9] & 0xFFFF) | (val << 16);
1780 1780
 				return;
1781 1781
 			case REG_IF:
1782 1782
 				REG_IF_WriteWord<ARMCPU_ARM9>(0, val);
... ...
@@ -1811,7 +1811,7 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
1811 1811
 				MMU_writeToGCControl<ARMCPU_ARM9>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF0000) | val);
1812 1812
 				return;
1813 1813
 			case REG_GCROMCTRL + 2:
1814
-				MMU_writeToGCControl<ARMCPU_ARM9>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF) | (static_cast<uint32_t>(val) << 16));
1814
+				MMU_writeToGCControl<ARMCPU_ARM9>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF) | (val << 16));
1815 1815
 				return;
1816 1816
 		}
1817 1817
 
... ...
@@ -1862,22 +1862,22 @@ void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
1862 1862
 		switch (adr)
1863 1863
 		{
1864 1864
 			case REG_SQRTCNT:
1865
-				MMU_new.sqrt.write16(static_cast<uint16_t>(val));
1865
+				MMU_new.sqrt.write16(val & 0xFFFF);
1866 1866
 				return;
1867 1867
 			case REG_DIVCNT:
1868
-				MMU_new.div.write16(static_cast<uint16_t>(val));
1868
+				MMU_new.div.write16(val & 0xFFFF);
1869 1869
 				return;
1870 1870
 
1871 1871
 			case REG_VRAMCNTA:
1872 1872
 			case REG_VRAMCNTE:
1873
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA), val & 0xFF);
1874
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 1), (val >> 8) & 0xFF);
1875
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 2), (val >> 16) & 0xFF);
1876
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 3), (val >> 24) & 0xFF);
1873
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA, val & 0xFF);
1874
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA + 1, (val >> 8) & 0xFF);
1875
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA + 2, (val >> 16) & 0xFF);
1876
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA + 3, (val >> 24) & 0xFF);
1877 1877
 				break;
1878 1878
 			case REG_VRAMCNTH:
1879
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA), val & 0xFF);
1880
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 1), (val >> 8) & 0xFF);
1879
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA, val & 0xFF);
1880
+				MMU_VRAMmapControl(adr - REG_VRAMCNTA + 1, (val >> 8) & 0xFF);
1881 1881
 				break;
1882 1882
 
1883 1883
 			case REG_IME:
... ...
@@ -1901,8 +1901,8 @@ void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
1901 1901
 			case REG_TM3CNTL:
1902 1902
 			{
1903 1903
 				int timerIndex = (adr >> 2) & 0x3;
1904
-				MMU.timerReload[ARMCPU_ARM9][timerIndex] = static_cast<uint16_t>(val);
1905
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & 0xFFF, static_cast<uint16_t>(val));
1904
+				MMU.timerReload[ARMCPU_ARM9][timerIndex] = val & 0xFFFF;
1905
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & 0xFFF, val & 0xFFFF);
1906 1906
 				write_timer(ARMCPU_ARM9, timerIndex, val >> 16);
1907 1907
 				return;
1908 1908
 			}
... ...
@@ -1946,7 +1946,7 @@ void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
1946 1946
 				MMU_IPCSync(ARMCPU_ARM9, val);
1947 1947
 				return;
1948 1948
 			case REG_IPCFIFOCNT:
1949
-				IPC_FIFOcnt(ARMCPU_ARM9, static_cast<uint16_t>(val));
1949
+				IPC_FIFOcnt(ARMCPU_ARM9, val & 0xFFFF);
1950 1950
 				return;
1951 1951
 			case REG_IPCFIFOSEND:
1952 1952
 				IPC_FIFOsend(ARMCPU_ARM9, val);
... ...
@@ -2001,18 +2001,18 @@ uint8_t FASTCALL _MMU_ARM9_read08(uint32_t adr)
2001 2001
 		//Address is an IO register
2002 2002
 
2003 2003
 		if (MMU_new.is_dma(adr))
2004
-			return static_cast<uint8_t>(MMU_new.read_dma(ARMCPU_ARM9, 8, adr));
2004
+			return MMU_new.read_dma(ARMCPU_ARM9, 8, adr) & 0xFF;
2005 2005
 
2006 2006
 		switch (adr)
2007 2007
 		{
2008 2008
 			case REG_IF:
2009
-				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>());
2009
+				return MMU.gen_IF<ARMCPU_ARM9>() & 0xFF;
2010 2010
 			case REG_IF + 1:
2011
-				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>() >> 8);
2011
+				return (MMU.gen_IF<ARMCPU_ARM9>() >> 8) & 0xFF;
2012 2012
 			case REG_IF + 2:
2013
-				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>() >> 16);
2013
+				return (MMU.gen_IF<ARMCPU_ARM9>() >> 16) & 0xFF;
2014 2014
 			case REG_IF + 3:
2015
-				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>() >> 24);
2015
+				return (MMU.gen_IF<ARMCPU_ARM9>() >> 24) & 0xFF;
2016 2016
 
2017 2017
 			case REG_WRAMCNT:
2018 2018
 				return MMU.WRAMCNT;
... ...
@@ -2068,7 +2068,7 @@ uint16_t FASTCALL _MMU_ARM9_read16(uint32_t adr)
2068 2068
 	if ((adr >> 24) == 4)
2069 2069
 	{
2070 2070
 		if (MMU_new.is_dma(adr))
2071
-			return static_cast<uint16_t>(MMU_new.read_dma(ARMCPU_ARM9, 16, adr));
2071
+			return MMU_new.read_dma(ARMCPU_ARM9, 16, adr) & 0xFFFF;
2072 2072
 
2073 2073
 		// Address is an IO register
2074 2074
 		switch (adr)
... ...
@@ -2088,21 +2088,21 @@ uint16_t FASTCALL _MMU_ARM9_read16(uint32_t adr)
2088 2088
 				return 0;
2089 2089
 
2090 2090
 			case REG_IME:
2091
-				return static_cast<uint16_t>(MMU.reg_IME[ARMCPU_ARM9]);
2091
+				return MMU.reg_IME[ARMCPU_ARM9] & 0xFFFF;
2092 2092
 
2093 2093
 			// WRAMCNT is readable but VRAMCNT is not, so just return WRAM's value
2094 2094
 			case REG_VRAMCNTG:
2095 2095
 				return MMU.WRAMCNT << 8;
2096 2096
 
2097 2097
 			case REG_IE:
2098
-				return static_cast<uint16_t>(MMU.reg_IE[ARMCPU_ARM9]);
2098
+				return MMU.reg_IE[ARMCPU_ARM9] & 0xFFFF;
2099 2099
 			case REG_IE + 2:
2100
-				return static_cast<uint16_t>(MMU.reg_IE[ARMCPU_ARM9] >> 16);
2100
+				return (MMU.reg_IE[ARMCPU_ARM9] >> 16) & 0xFFFF;
2101 2101
 
2102 2102
 			case REG_IF:
2103
-				return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM9>());
2103
+				return MMU.gen_IF<ARMCPU_ARM9>() & 0xFFFF;
2104 2104
 			case REG_IF + 2:
2105
-				return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM9>() >> 16);
2105
+				return (MMU.gen_IF<ARMCPU_ARM9>() >> 16) & 0xFFFF;
2106 2106
 
2107 2107
 			case REG_TM0CNTL:
2108 2108
 			case REG_TM1CNTL:
... ...
@@ -2372,7 +2372,7 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2372 2372
 							else
2373 2373
 							{
2374 2374
 								// write
2375
-								MMU.powerMan_Reg[reg] = static_cast<uint8_t>(val);
2375
+								MMU.powerMan_Reg[reg] = val & 0xFF;
2376 2376
 
2377 2377
 								static const uint32_t PM_SYSTEM_PWR = BIT(6); /*!< \brief  Turn the power *off* if set */
2378 2378
 
... ...
@@ -2395,7 +2395,7 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2395 2395
 							T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, 0);
2396 2396
 							break;
2397 2397
 						}
2398
-						T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, static_cast<uint8_t>(val)));
2398
+						T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, val & 0xFF));
2399 2399
 						return;
2400 2400
 
2401 2401
 					case 2:
... ...
@@ -2526,7 +2526,7 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2526 2526
 				return;
2527 2527
 			case REG_IE + 2:
2528 2528
 				NDS_Reschedule();
2529
-				MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7] & 0xFFFF) | (static_cast<uint32_t>(val) << 16);
2529
+				MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7] & 0xFFFF) | (val << 16);
2530 2530
 				return;
2531 2531
 
2532 2532
 			case REG_IF:
... ...
@@ -2563,7 +2563,7 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
2563 2563
 				MMU_writeToGCControl<ARMCPU_ARM7>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF0000) | val);
2564 2564
 				return;
2565 2565
 			case REG_GCROMCTRL + 2:
2566
-				MMU_writeToGCControl<ARMCPU_ARM7>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF) | (static_cast<uint32_t>(val) << 16));
2566
+				MMU_writeToGCControl<ARMCPU_ARM7>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF) | (val << 16));
2567 2567
 				return;
2568 2568
 		}
2569 2569
 
... ...
@@ -2628,8 +2628,8 @@ void FASTCALL _MMU_ARM7_write32(uint32_t adr, uint32_t val)
2628 2628
 			case REG_TM3CNTL:
2629 2629
 			{
2630 2630
 				int timerIndex = (adr >> 2) & 0x3;
2631
-				MMU.timerReload[ARMCPU_ARM7][timerIndex] = static_cast<uint16_t>(val);
2632
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & 0xFFF, static_cast<uint16_t>(val));
2631
+				MMU.timerReload[ARMCPU_ARM7][timerIndex] = val & 0xFFFF;
2632
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & 0xFFF, val & 0xFFFF);
2633 2633
 				write_timer(ARMCPU_ARM7, timerIndex, val >> 16);
2634 2634
 				return;
2635 2635
 			}
... ...
@@ -2638,7 +2638,7 @@ void FASTCALL _MMU_ARM7_write32(uint32_t adr, uint32_t val)
2638 2638
 				MMU_IPCSync(ARMCPU_ARM7, val);
2639 2639
 				return;
2640 2640
 			case REG_IPCFIFOCNT:
2641
-				IPC_FIFOcnt(ARMCPU_ARM7, static_cast<uint16_t>(val));
2641
+				IPC_FIFOcnt(ARMCPU_ARM7, val & 0xFFFF);
2642 2642
 				return;
2643 2643
 			case REG_IPCFIFOSEND:
2644 2644
 				IPC_FIFOsend(ARMCPU_ARM7, val);
... ...
@@ -2690,20 +2690,20 @@ uint8_t FASTCALL _MMU_ARM7_read08(uint32_t adr)
2690 2690
 	if ((adr >> 24) == 4)
2691 2691
 	{
2692 2692
 		if (MMU_new.is_dma(adr))
2693
-			return static_cast<uint8_t>(MMU_new.read_dma(ARMCPU_ARM7, 8, adr));
2693
+			return MMU_new.read_dma(ARMCPU_ARM7, 8, adr) & 0xFF;
2694 2694
 
2695 2695
 		// Address is an IO register
2696 2696
 
2697 2697
 		switch (adr)
2698 2698
 		{
2699 2699
 			case REG_IF:
2700
-				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>());
2700
+				return MMU.gen_IF<ARMCPU_ARM7>() & 0xFF;
2701 2701
 			case REG_IF + 1:
2702
-				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>() >> 8);
2702
+				return (MMU.gen_IF<ARMCPU_ARM7>() >> 8) & 0xFF;
2703 2703
 			case REG_IF + 2:
2704
-				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>() >> 16);
2704
+				return (MMU.gen_IF<ARMCPU_ARM7>() >> 16) & 0xFF;
2705 2705
 			case REG_IF + 3:
2706
-				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>() >> 24);
2706
+				return (MMU.gen_IF<ARMCPU_ARM7>() >> 24) & 0xFF;
2707 2707
 
2708 2708
 			case REG_WRAMSTAT:
2709 2709
 				return MMU.WRAMCNT;
... ...
@@ -2737,22 +2737,22 @@ uint16_t FASTCALL _MMU_ARM7_read16(uint32_t adr)
2737 2737
 		// Address is an IO register
2738 2738
 
2739 2739
 		if (MMU_new.is_dma(adr))
2740
-			return static_cast<uint16_t>(MMU_new.read_dma(ARMCPU_ARM7, 16, adr));
2740
+			return MMU_new.read_dma(ARMCPU_ARM7, 16, adr) & 0xFFFF;
2741 2741
 
2742 2742
 		switch (adr)
2743 2743
 		{
2744 2744
 			case REG_IME:
2745
-				return static_cast<uint16_t>(MMU.reg_IME[ARMCPU_ARM7]);
2745
+				return MMU.reg_IME[ARMCPU_ARM7] & 0xFFFF;
2746 2746
 
2747 2747
 			case REG_IE:
2748
-				return static_cast<uint16_t>(MMU.reg_IE[ARMCPU_ARM7]);
2748
+				return MMU.reg_IE[ARMCPU_ARM7] & 0xFFFF;
2749 2749
 			case REG_IE + 2:
2750
-				return static_cast<uint16_t>(MMU.reg_IE[ARMCPU_ARM7] >> 16);
2750
+				return (MMU.reg_IE[ARMCPU_ARM7] >> 16) & 0xFFFF;
2751 2751
 
2752 2752
 			case REG_IF:
2753
-				return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM7>());
2753
+				return MMU.gen_IF<ARMCPU_ARM7>() & 0xFFFF;
2754 2754
 			case REG_IF + 2:
2755
-				return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM7>() >> 16);
2755
+				return (MMU.gen_IF<ARMCPU_ARM7>() >> 16) & 0xFFFF;
2756 2756
 
2757 2757
 			case REG_TM0CNTL:
2758 2758
 			case REG_TM1CNTL:
Browse code

Updating in_2sf to use a newish version of DeSmuME, 0.9.9 from SVN. Somewhat cleaned up as well, but not everything because it's a pain in the ass.

Naram Qashat authored on 2013/04/18 17:22:55
Showing 1 changed files
... ...
@@ -22,62 +22,46 @@
22 22
 #include <cmath>
23 23
 #include <cstring>
24 24
 #include <cassert>
25
-
26
-#include "common.h"
27
-//#include "debug.h"
28 25
 #include "NDSSystem.h"
29 26
 #include "cp15.h"
30
-//#include "wifi.h"
31 27
 #include "registers.h"
32
-//#include "render3D.h"
33
-//#include "gfx3d.h"
34
-//#include "rtc.h"
35 28
 #include "mc.h"
36
-//#include "addons.h"
37 29
 #include "slot1.h"
38
-//#include "mic.h"
39
-//#include "movie.h"
40 30
 #include "readwrite.h"
41 31
 #include "MMU_timing.h"
42 32
 
43
-//#undef min
44
-
45
-/*#ifdef DO_ASSERT_UNALIGNED
46
-#define ASSERT_UNALIGNED(x) assert(x)
47
-#else
48
-#define ASSERT_UNALIGNED(x)
49
-#endif*/
50
-
51
-//http://home.utah.edu/~nahaj/factoring/isqrt.c.html
52
-static uint64_t isqrt (uint64_t x) {
53
-  uint64_t   squaredbit, remainder, root;
54
-
55
-   if (x<1) return 0;
56
-
57
-   /* Load the binary constant 01 00 00 ... 00, where the number
58
-    * of zero bits to the right of the single one bit
59
-    * is even, and the one bit is as far left as is consistant
60
-    * with that condition.)
61
-    */
62
-   squaredbit  = (uint64_t) ((((uint64_t) ~0LL) >> 1) &
63
-                        ~(((uint64_t) ~0LL) >> 2));
64
-   /* This portable load replaces the loop that used to be
65
-    * here, and was donated by  legalize@xmission.com
66
-    */
67
-
68
-   /* Form bits of the answer. */
69
-   remainder = x;  root = 0;
70
-   while (squaredbit > 0) {
71
-     if (remainder >= (squaredbit | root)) {
72
-         remainder -= (squaredbit | root);
73
-         root >>= 1; root |= squaredbit;
74
-     } else {
75
-         root >>= 1;
76
-     }
77
-     squaredbit >>= 2;
78
-   }
79
-
80
-   return root;
33
+// http://home.utah.edu/~nahaj/factoring/isqrt.c.html
34
+static uint64_t isqrt(uint64_t x)
35
+{
36
+	if (x < 1)
37
+		return 0;
38
+
39
+	/* Load the binary constant 01 00 00 ... 00, where the number
40
+	 * of zero bits to the right of the single one bit
41
+	 * is even, and the one bit is as far left as is consistant
42
+	 * with that condition.)
43
+	 */
44
+	uint64_t squaredbit = static_cast<uint64_t>((static_cast<uint64_t>(~0LL) >> 1) & ~(static_cast<uint64_t>(~0LL) >> 2));
45
+	/* This portable load replaces the loop that used to be
46
+	 * here, and was donated by  legalize@xmission.com
47
+	 */
48
+
49
+	/* Form bits of the answer. */
50
+	uint64_t remainder = x, root = 0;
51
+	while (squaredbit > 0)
52
+	{
53
+		if (remainder >= (squaredbit | root))
54
+		{
55
+			remainder -= squaredbit | root;
56
+			root >>= 1;
57
+			root |= squaredbit;
58
+		}
59
+		else
60
+			root >>= 1;
61
+		squaredbit >>= 2;
62
+	}
63
+
64
+	return root;
81 65
 }
82 66
 
83 67
 uint32_t partie = 1;
... ...
@@ -85,83 +69,12 @@ uint32_t _MMU_MAIN_MEM_MASK = 0x3FFFFF;
85 69
 uint32_t _MMU_MAIN_MEM_MASK16 = 0x3FFFFF & ~1;
86 70
 uint32_t _MMU_MAIN_MEM_MASK32 = 0x3FFFFF & ~3;
87 71
 
88
-//#define	_MMU_DEBUG
89
-
90
-/*#ifdef _MMU_DEBUG
91
-
92
-#include <stdarg.h>
93
-void mmu_log_debug_ARM9(uint32_t adr, const char *fmt, ...)
94
-{
95
-	if (adr < 0x4000000) return;
96
-//	if (adr > 0x4100014) return;
97
-//#if 1
98
-	if (adr >= 0x4000000 && adr <= 0x400006E) return;		// Display Engine A
99
-	if (adr >= 0x40000B0 && adr <= 0x4000134) return;		// DMA, Timers and Keypad
100
-	if (adr >= 0x4000180 && adr <= 0x40001BC) return;		// IPC/ROM
101
-	if (adr >= 0x4000204 && adr <= 0x400024A) return;		// Memory & IRQ control
102
-	if (adr >= 0x4000280 && adr <= 0x4000306) return;		// Maths
103
-	if (adr >= 0x4000320 && adr <= 0x40006A3) return;		// 3D dispaly engine
104
-	if (adr >= 0x4001000 && adr <= 0x400106E) return;		// Display Engine B
105
-	if (adr >= 0x4100000 && adr <= 0x4100014) return;		// IPC/ROM
106
-//#endif
107
-	va_list list;
108
-	char msg[512];
109
-
110
-	memset(msg,0,512);
111
-
112
-	va_start(list,fmt);
113
-		_vsnprintf(msg,511,fmt,list);
114
-	va_end(list);
115
-
116
-	INFO("MMU ARM9 0x%08X: %s\n", adr, msg);
117
-}
118
-
119
-void mmu_log_debug_ARM7(uint32_t adr, const char *fmt, ...)
120
-{
121
-	if (adr < 0x4000004) return;
122
-	if (adr > 0x4808FFF) return;
123
-#if 1
124
-	if (adr >= 0x4000004 && adr < 0x4000180) return;		// ARM7 I/O Map
125
-	if (adr >= 0x4000180 && adr <= 0x40001C4) return;		// IPC/ROM
126
-	if (adr >= 0x4000204 && adr <= 0x400030C) return;		// Memory and IRQ Control
127
-	if (adr >= 0x4000400 && adr <= 0x400051E) return;		// Sound Registers
128
-	if (adr >= 0x4100000 && adr <= 0x4100014) return;		// IPC/ROM
129
-	if (adr >= 0x4800000 && adr <= 0x4808FFF) return;		// WLAN Registers
130
-#endif
131
-	va_list list;
132
-	char msg[512];
133
-
134
-	memset(msg,0,512);
135
-
136
-	va_start(list,fmt);
137
-		_vsnprintf(msg,511,fmt,list);
138
-	va_end(list);
139
-
140
-	INFO("MMU ARM7 0x%08X: %s\n", adr, msg);
141
-
142
-}
143
-#else
144
-#define mmu_log_debug_ARM9(...)
145
-#define mmu_log_debug_ARM7(...)
146
-#endif*/
147
-
148
-
149
-//#define LOG_CARD
150
-//#define LOG_GPU
151
-//#define LOG_DMA
152
-//#define LOG_DMA2
153
-//#define LOG_DIV
154
-
155
-#define DUP2(x)  x, x
156
-#define DUP4(x)  x, x, x, x
157
-#define DUP8(x)  x, x, x, x,  x, x, x, x
158
-#define DUP16(x) x, x, x, x,  x, x, x, x,  x, x, x, x,  x, x, x, x
159
-
160 72
 MMU_struct MMU;
161 73
 MMU_struct_new MMU_new;
162 74
 MMU_struct_timing MMU_timing;
163 75
 
164
-uint8_t * MMU_struct::MMU_MEM[2][256] = {
76
+uint8_t *MMU_struct::MMU_MEM[2][256] =
77
+{
165 78
 	//arm9
166 79
 	{
167 80
 		/* 0X*/	DUP16(MMU.ARM9_ITCM),
... ...
@@ -173,8 +86,8 @@ uint8_t * MMU_struct::MMU_MEM[2][256] = {
173 86
 		/* 5X*/	DUP16(MMU.ARM9_VMEM),
174 87
 		/* 6X*/	DUP16(MMU.ARM9_LCD),
175 88
 		/* 7X*/	DUP16(MMU.ARM9_OAM),
176
-		/* 8X*/	DUP16(NULL),
177
-		/* 9X*/	DUP16(NULL),
89
+		/* 8X*/	DUP16(nullptr),
90
+		/* 9X*/	DUP16(nullptr),
178 91
 		/* AX*/	DUP16(MMU.UNUSED_RAM),
179 92
 		/* BX*/	DUP16(MMU.UNUSED_RAM),
180 93
 		/* CX*/	DUP16(MMU.UNUSED_RAM),
... ...
@@ -194,18 +107,19 @@ uint8_t * MMU_struct::MMU_MEM[2][256] = {
194 107
 		/* 5X*/	DUP16(MMU.UNUSED_RAM),
195 108
 		/* 6X*/	DUP16(MMU.ARM9_LCD),
196 109
 		/* 7X*/	DUP16(MMU.UNUSED_RAM),
197
-		/* 8X*/	DUP16(NULL),
198
-		/* 9X*/	DUP16(NULL),
110
+		/* 8X*/	DUP16(nullptr),
111
+		/* 9X*/	DUP16(nullptr),
199 112
 		/* AX*/	DUP16(MMU.UNUSED_RAM),
200 113
 		/* BX*/	DUP16(MMU.UNUSED_RAM),
201 114
 		/* CX*/	DUP16(MMU.UNUSED_RAM),
202 115
 		/* DX*/	DUP16(MMU.UNUSED_RAM),
203 116
 		/* EX*/	DUP16(MMU.UNUSED_RAM),
204 117
 		/* FX*/	DUP16(MMU.UNUSED_RAM)
205
-		}
118
+	}
206 119
 };
207 120
 
208
-uint32_t MMU_struct::MMU_MASK[2][256] = {
121
+uint32_t MMU_struct::MMU_MASK[2][256] =
122
+{
209 123
 	//arm9
210 124
 	{
211 125
 		/* 0X*/	DUP16(0x00007FFF),
... ...
@@ -246,438 +160,434 @@ uint32_t MMU_struct::MMU_MASK[2][256] = {
246 160
 		/* DX*/	DUP16(0x00000003),
247 161
 		/* EX*/	DUP16(0x00000003),
248 162
 		/* FX*/	DUP16(0x00000003)
249
-		}
163
+	}
250 164
 };
251 165
 
252
-// this logic was moved to MMU_timing.h
253
-//CACHE_ALIGN
254
-//TWaitState MMU_struct::MMU_WAIT16[2][16] = {
255
-//	{ 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1 }, //arm9
256
-//	{ 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1 }, //arm7
257
-//};
258
-//
259
-//CACHE_ALIGN
260
-//TWaitState MMU_struct::MMU_WAIT32[2][16] = {
261
-//	{ 1, 1, 1, 1, 1, 2, 2, 1, 8, 8, 5, 1, 1, 1, 1, 1 }, //arm9
262
-//	{ 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 5, 1, 1, 1, 1, 1 }, //arm7
263
-//};
264
-
265 166
 //////////////////////////////////////////////////////////////
266 167
 
267
-//-------------
268
-//VRAM MEMORY MAPPING
269
-//-------------
270
-//(Everything is mapped through to ARM9_LCD in blocks of 16KB)
168
+// -------------
169
+// VRAM MEMORY MAPPING
170
+// -------------
171
+// (Everything is mapped through to ARM9_LCD in blocks of 16KB)
271 172
 
272
-//for all of the below, values = 41 indicate unmapped memory
173
+// for all of the below, values = 41 indicate unmapped memory
273 174
 static const uint8_t VRAM_PAGE_UNMAPPED = 41;
274 175
 
275 176
 static const unsigned VRAM_LCDC_PAGES = 41;
276 177
 uint8_t vram_lcdc_map[VRAM_LCDC_PAGES];
277 178
 
278
-//in the range of 0x06000000 - 0x06800000 in 16KB pages (the ARM9 vram mappable area)
279
-//this maps to 16KB pages in the LCDC buffer which is what will actually contain the data
179
+// in the range of 0x06000000 - 0x06800000 in 16KB pages (the ARM9 vram mappable area)
180
+// this maps to 16KB pages in the LCDC buffer which is what will actually contain the data
280 181
 uint8_t vram_arm9_map[VRAM_ARM9_PAGES];
281 182
 
282
-//this chooses which banks are mapped in the 128K banks starting at 0x06000000 in ARM7
183
+// this chooses which banks are mapped in the 128K banks starting at 0x06000000 in ARM7
283 184
 uint8_t vram_arm7_map[2];
284 185
 
285
-//----->
286
-//consider these later, for better recordkeeping, instead of using the uint8_t* in MMU
287
-
288
-////for each 128KB texture slot, this maps to a 16KB starting page in the LCDC buffer
289
-//#define VRAM_TEX_SLOTS 4
290
-//uint8_t vram_tex_map[VRAM_TEX_SLOTS];
291
-//
292
-////for each 16KB tex palette slot, this maps to a 16KB starting page in the LCDC buffer
293
-//#define VRAM_TEX_PALETTE_SLOTS 6
294
-//uint8_t vram_tex_palette_map[VRAM_TEX_PALETTE_SLOTS];
295
-
296
-//<---------
297
-
298
-
299
-//void MMU_VRAM_unmap_all();
300
-
301
-struct TVramBankInfo {
186
+struct TVramBankInfo
187
+{
302 188
 	uint8_t page_addr, num_pages;
303 189
 };
304 190
 
305
-static const TVramBankInfo vram_bank_info[VRAM_BANKS] = {
306
-	{0,8},
307
-	{8,8},
308
-	{16,8},
309
-	{24,8},
310
-	{32,4},
311
-	{36,1},
312
-	{37,1},
313
-	{38,2},
314
-	{40,1}
191
+static const TVramBankInfo vram_bank_info[VRAM_BANKS] =
192
+{
193
+	{0, 8},
194
+	{8, 8},
195
+	{16, 8},
196
+	{24, 8},
197
+	{32, 4},
198
+	{36, 1},
199
+	{37, 1},
200
+	{38, 2},
201
+	{40, 1}
315 202
 };
316 203
 
317
-//this is to remind you that the LCDC mapping returns a strange value (not 0x06800000) as you would expect
318
-//in order to play nicely with the MMU address and mask tables
204
+// this is to remind you that the LCDC mapping returns a strange value (not 0x06800000) as you would expect
205
+// in order to play nicely with the MMU address and mask tables
319 206
 static const uint32_t LCDC_HACKY_LOCATION = 0x06000000;
320 207
 
321
-//maps an ARM9 BG/OBJ or LCDC address into an LCDC address, and informs the caller of whether it isn't mapped
322
-//TODO - in cases where this does some mapping work, we could bypass the logic at the end of the _read* and _write* routines
323
-//this is a good optimization to consider
324
-//template<int PROCNUM>
325
-static inline uint32_t MMU_LCDmap(uint32_t addr, bool& unmapped, bool& restricted)
208
+static const uint32_t ARM7_HACKY_IWRAM_LOCATION = 0x03800000;
209
+static const uint32_t ARM7_HACKY_SIWRAM_LOCATION = 0x03000000;
210
+
211
+// maps an ARM9 BG/OBJ or LCDC address into an LCDC address, and informs the caller of whether it isn't mapped
212
+// TODO - in cases where this does some mapping work, we could bypass the logic at the end of the _read* and _write* routines
213
+// this is a good optimization to consider
214
+// NOTE - this whole approach is probably fundamentally wrong.
215
+// according to dasShiny research, its possible to map multiple banks to the same addresses. something more sophisticated would be needed.
216
+// however, it hasnt proven necessary yet for any known test case.
217
+template<int PROCNUM> static inline uint32_t MMU_LCDmap(uint32_t addr, bool &unmapped, bool &restricted)
326 218
 {
327 219
 	unmapped = false;
328
-	restricted = false; //this will track whether 8bit writes are allowed
329
-
330
-	//in case the address is entirely outside of the interesting ranges
331
-	if(addr < 0x06000000) return addr;
332
-	if(addr >= 0x07000000) return addr;
220
+	restricted = false; // this will track whether 8bit writes are allowed
221
+
222
+	// handle SIWRAM and non-shared IWRAM in here too, since it is quite similar to vram.
223
+	// in fact it is probably implemented with the same pieces of hardware.
224
+	// its sort of like arm7 non-shared IWRAM is lowest priority, and then SIWRAM goes on top.
225
+	// however, we implement it differently than vram in emulator for historical reasons.
226
+	// instead of keeping a page map like we do vram, we just have a list of all possible page maps (there are only 4 each for arm9 and arm7)
227
+	if (addr >= 0x03000000 && addr < 0x04000000)
228
+	{
229
+		// blocks 0,1,2,3 is arm7 non-shared IWRAM and blocks 4,5 is SIWRAM, and block 8 is un-mapped zeroes
230
+		int iwram_block_16k;
231
+		int iwram_offset = addr & 0x3FFF;
232
+		addr &= 0x00FFFFFF;
233
+		if (PROCNUM == ARMCPU_ARM7)
234
+		{
235
+			static const int arm7_siwram_blocks[][4][4] =
236
+			{
237
+				{
238
+					{0, 1, 2, 3}, //WRAMCNT = 0 -> map to IWRAM
239
+					{4, 4, 4, 4}, //WRAMCNT = 1 -> map to SIWRAM block 0
240
+					{5, 5, 5, 5}, //WRAMCNT = 2 -> map to SIWRAM block 1
241
+					{4, 5, 4, 5}, //WRAMCNT = 3 -> map to SIWRAM blocks 0,1
242
+				},
243
+				//high region; always maps to non-shared IWRAM
244
+				{
245
+					{0, 1, 2, 3},
246
+					{0, 1, 2, 3},
247
+					{0, 1, 2, 3},
248
+					{0, 1, 2, 3}
249
+				}
250
+			};
251
+			int region = (addr >> 23) & 1;
252
+			int block = (addr >> 14) & 3;
253
+			assert(region < 2);
254
+			assert(block < 4);
255
+			iwram_block_16k = arm7_siwram_blocks[region][MMU.WRAMCNT][block];
256
+		} //PROCNUM == ARMCPU_ARM7
257
+		else
258
+		{
259
+			// PROCNUM == ARMCPU_ARM9
260
+			static const int arm9_siwram_blocks[][4] =
261
+			{
262
+				{4, 5, 4, 5}, //WRAMCNT = 0 -> map to SIWRAM blocks 0,1
263
+				{5, 5, 5, 5}, //WRAMCNT = 1 -> map to SIWRAM block 1
264
+				{4, 4, 4, 4}, //WRAMCNT = 2 -> map to SIWRAM block 0
265
+				{8, 8, 8, 8}, //WRAMCNT = 3 -> unmapped
266
+			};
267
+			int block = (addr >> 14) & 3;
268
+			assert(block < 4);
269
+			iwram_block_16k = arm9_siwram_blocks[MMU.WRAMCNT][block];
270
+		}
333 271
 
334
-	//shared wram mapping for arm7
335
-	/*if(PROCNUM==ARMCPU_ARM7)
336
-	{
337
-		//necessary? not sure
338
-		//addr &= 0x3FFFF;
339
-		//addr += 0x06000000;
340
-		uint32_t ofs = addr & 0x1FFFF;
341
-		uint32_t bank = (addr >> 17)&1;
342
-		if(vram_arm7_map[bank] == VRAM_PAGE_UNMAPPED)
272
+		switch (iwram_block_16k >> 2)
343 273
 		{
344
-			unmapped = true;
345
-			return 0;
274
+			case 0: // arm7 non-shared IWRAM
275
+				return ARM7_HACKY_IWRAM_LOCATION + (iwram_block_16k << 14) + iwram_offset;
276
+			case 1: //SIWRAM
277
+				return ARM7_HACKY_SIWRAM_LOCATION + ((iwram_block_16k & 3) << 14) + iwram_offset;
278
+			case 2: //zeroes
279
+			CASE2:
280
+				unmapped = true;
281
+				return 0;
282
+			default:
283
+				assert(false); //how did this happen?
284
+				goto CASE2;
346 285
 		}
347
-		return LCDC_HACKY_LOCATION + (vram_arm7_map[bank]<<14) + ofs;
348
-	}*/
286
+	}
287
+
288
+	// in case the address is entirely outside of the interesting VRAM ranges
289
+	if (addr < 0x06000000)
290
+		return addr;
291
+	if (addr >= 0x07000000)
292
+		return addr;
349 293
 
350 294
 	restricted = true;
351 295
 
352
-	//handle LCD memory mirroring
353
-	if(addr>=0x068A4000)
296
+	// handle LCD memory mirroring
297
+	// TODO - this is gross! this should be renovated if the vram mapping is ever done in a more sophisticated way taking into account dasShiny research
298
+	if (addr >= 0x068A4000)
354 299
 		addr = 0x06800000 +
355
-		//(addr%0xA4000); //yuck!! is this even how it mirrors? but we have to keep from overrunning the buffer somehow
356
-		(addr&0x80000); //just as likely to be right (I have no clue how it should work) but faster.
300
+		//(addr % 0xA4000); // yuck!! is this even how it mirrors? but we have to keep from overrunning the buffer somehow
301
+		(addr & 0x80000); // just as likely to be right (I have no clue how it should work) but faster.
357 302
 
358 303
 	uint32_t vram_page;
359 304
 	uint32_t ofs = addr & 0x3FFF;
360 305
 
361
-	//return addresses in LCDC range
362
-	if(addr>=0x06800000)
306
+	// return addresses in LCDC range
307
+	if (addr >= 0x06800000)
363 308
 	{
364
-		//already in LCDC range. just look it up to see whether it is unmapped
365
-		vram_page = (addr>>14)&63;
366
-		assert(vram_page<VRAM_LCDC_PAGES);
309
+		// already in LCDC range. just look it up to see whether it is unmapped
310
+		vram_page = (addr >> 14) & 63;
311
+		assert(vram_page < VRAM_LCDC_PAGES);
367 312
 		vram_page = vram_lcdc_map[vram_page];
368 313
 	}
369 314
 	else
370 315
 	{
371
-		//map addresses in BG/OBJ range to an LCDC range
372
-		vram_page = (addr>>14)&(VRAM_ARM9_PAGES-1);
373
-		assert(vram_page<VRAM_ARM9_PAGES);
316
+		// map addresses in BG/OBJ range to an LCDC range
317
+		vram_page = (addr >> 14) & (VRAM_ARM9_PAGES - 1);
318
+		assert(vram_page < VRAM_ARM9_PAGES);
374 319
 		vram_page = vram_arm9_map[vram_page];
375 320
 	}
376 321
 
377
-	if(vram_page == VRAM_PAGE_UNMAPPED)
322
+	if (vram_page == VRAM_PAGE_UNMAPPED)
378 323
 	{
379 324
 		unmapped = true;
380 325
 		return 0;
381 326
 	}
382 327
 	else
383
-		return LCDC_HACKY_LOCATION + (vram_page<<14) + ofs;
328
+		return LCDC_HACKY_LOCATION + (vram_page << 14) + ofs;
384 329
 }
385 330
 
386
-
387
-//#define LOG_VRAM_ERROR() LOG("No data for block %i MST %i\n", block, VRAMBankCnt & 0x07);
388
-
389 331
 VramConfiguration vramConfiguration;
390 332
 
391
-/*std::string VramConfiguration::describePurpose(Purpose p) {
392
-	switch(p) {
393
-		case OFF: return "OFF";
394
-		case INVALID: return "INVALID";
395
-		case ABG: return "ABG";
396
-		case BBG: return "BBG";
397
-		case AOBJ: return "AOBJ";
398
-		case BOBJ: return "BOBJ";
399
-		case LCDC: return "LCDC";
400
-		case ARM7: return "ARM7";
401
-		case TEX: return "TEX";
402
-		case TEXPAL: return "TEXPAL";
403
-		case ABGEXTPAL: return "ABGEXTPAL";
404
-		case BBGEXTPAL: return "BBGEXTPAL";
405
-		case AOBJEXTPAL: return "AOBJEXTPAL";
406
-		case BOBJEXTPAL: return "BOBJEXTPAL";
407
-		default: return "UNHANDLED CASE";
408
-	}
409
-}
410
-
411
-std::string VramConfiguration::describe() {
412
-	std::stringstream ret;
413
-	for(int i=0;i<VRAM_BANKS;i++) {
414
-		ret << (char)(i+'A') << ": " << banks[i].ofs << " " << describePurpose(banks[i].purpose) << std::endl;
415
-	}
416
-	return ret.str();
417
-}*/
418
-
419
-//maps the specified bank to LCDC
420
-static inline void MMU_vram_lcdc(const int bank)
333
+// maps the specified bank to LCDC
334
+static inline void MMU_vram_lcdc(int bank)
421 335
 {
422
-	for(int i=0;i<vram_bank_info[bank].num_pages;i++)
336
+	for (int i = 0; i < vram_bank_info[bank].num_pages; ++i)
423 337
 	{
424
-		int page = vram_bank_info[bank].page_addr+i;
338
+		int page = vram_bank_info[bank].page_addr + i;
425 339
 		vram_lcdc_map[page] = page;
426 340
 	}
427 341
 }
428 342
 
429
-//maps the specified bank to ARM9 at the provided page offset
430
-static inline void MMU_vram_arm9(const int bank, const int offset)
343
+// maps the specified bank to ARM9 at the provided page offset
344
+static inline void MMU_vram_arm9(int bank, int offset)
431 345
 {
432
-	for(int i=0;i<vram_bank_info[bank].num_pages;i++)
433
-	{
434
-		int page = vram_bank_info[bank].page_addr+i;
435
-
436
-		vram_arm9_map[i+offset] = page;
437
-	}
346
+	for (int i = 0; i < vram_bank_info[bank].num_pages; ++i)
347
+		vram_arm9_map[i + offset] = vram_bank_info[bank].page_addr + i;
438 348
 }
439 349
 
440
-static inline uint8_t* MMU_vram_physical(const int page)
350
+static inline uint8_t *MMU_vram_physical(int page)
441 351
 {
442 352
 	return MMU.ARM9_LCD + (page/**ADDRESS_STEP_16KB*/);
443 353
 }
444 354
 
445
-//todo - templateize
446
-static inline void MMU_VRAMmapRefreshBank(const int bank)
355
+// todo - templateize
356
+static inline void MMU_VRAMmapRefreshBank(int bank)
447 357
 {
448 358
 	int block = bank;
449
-	if(bank >= VRAM_BANK_H) block++;
359
+	if (bank >= VRAM_BANK_H)
360
+		++block;
450 361
 
451 362
 	uint8_t VRAMBankCnt = T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x240 + block);
452 363
 
453
-	//do nothing if the bank isnt enabled
364
+	// do nothing if the bank isnt enabled
454 365
 	uint8_t en = VRAMBankCnt & 0x80;
455
-	if(!en) return;
366
+	if (!en)
367
+		return;
456 368
 
457
-	int mst,ofs=0;
458
-	switch(bank) {
369
+	int mst, ofs = 0;
370
+	switch (bank)
371
+	{
459 372
 		case VRAM_BANK_A:
460 373
 		case VRAM_BANK_B:
461 374
 			mst = VRAMBankCnt & 3;
462
-			ofs = (VRAMBankCnt>>3) & 3;
463
-			switch(mst)
375
+			ofs = (VRAMBankCnt >> 3) & 3;
376
+			switch (mst)
464 377
 			{
465
-			case 0: //LCDC
466
-				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
467
-				MMU_vram_lcdc(bank);
468
-				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
469
-				break;
470
-			case 1: //ABG
471
-				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
472
-				MMU_vram_arm9(bank,VRAM_PAGE_ABG+ofs*8);
473
-				break;
474
-			case 2: //AOBJ
475
-				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
476
-				switch(ofs) {
477
-				case 0:
478
-				case 1:
479
-					MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+ofs*8);
378
+				case 0: // LCDC
379
+					vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
380
+					MMU_vram_lcdc(bank);
480 381
 					break;
481
-				//default:
482
-					//PROGINFO("Unsupported ofs setting %d for engine A OBJ vram bank %c\n", ofs, 'A'+bank);
483
-				}
484
-				break;
485
-			case 3: //texture
486
-				vramConfiguration.banks[bank].purpose = VramConfiguration::TEX;
487
-				MMU.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
488
-				break;
489
-			default: goto unsupported_mst;
382
+				case 1: // ABG
383
+					vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
384
+					MMU_vram_arm9(bank, VRAM_PAGE_ABG + ofs * 8);
385
+					break;
386
+				case 2: // AOBJ
387
+					vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
388
+					switch (ofs)
389
+					{
390
+						case 0:
391
+						case 1:
392
+							MMU_vram_arm9(bank, VRAM_PAGE_AOBJ + ofs * 8);
393
+					}
394
+					break;
395
+				case 3: // texture
396
+					vramConfiguration.banks[bank].purpose = VramConfiguration::TEX;
397
+					MMU.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
398
+					break;
399
+				default:
400
+					goto unsupported_mst;
490 401
 			}
491 402
 			break;
492 403
 
493 404
 		case VRAM_BANK_C:
494 405
 		case VRAM_BANK_D:
495 406
 			mst = VRAMBankCnt & 7;
496
-			ofs = (VRAMBankCnt>>3) & 3;
497
-			switch(mst)
407
+			ofs = (VRAMBankCnt >> 3) & 3;
408
+			switch (mst)
498 409
 			{
499
-			case 0: //LCDC
500
-				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
501
-				MMU_vram_lcdc(bank);
502
-				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
503
-				break;
504
-			case 1: //ABG
505
-				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
506
-				MMU_vram_arm9(bank,VRAM_PAGE_ABG+ofs*8);
507
-				break;
508
-			case 2: //arm7
509
-				vramConfiguration.banks[bank].purpose = VramConfiguration::ARM7;
510
-				if(bank == 2) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 1);
511
-				if(bank == 3) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 2);
512
-				switch(ofs) {
513
-				case 0:
514
-				case 1:
515
-					vram_arm7_map[ofs] = vram_bank_info[bank].page_addr;
410
+				case 0: // LCDC
411
+					vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
412
+					MMU_vram_lcdc(bank);
516 413
 					break;
517
-				//default:
518
-					//PROGINFO("Unsupported ofs setting %d for arm7 vram bank %c\n", ofs, 'A'+bank);
519
-				}
520
-
521
-				break;
522
-			case 3: //texture
523
-				vramConfiguration.banks[bank].purpose = VramConfiguration::TEX;
524
-				MMU.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
525
-				break;
526
-			case 4: //BGB or BOBJ
527
-				if(bank == VRAM_BANK_C)  {
528
-					vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
529
-					MMU_vram_arm9(bank,VRAM_PAGE_BBG); //BBG
530
-				} else {
531
-					vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJ;
532
-					MMU_vram_arm9(bank,VRAM_PAGE_BOBJ); //BOBJ
533
-				}
534
-				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
535
-				break;
536
-			default: goto unsupported_mst;
414
+				case 1: // ABG
415
+					vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
416
+					MMU_vram_arm9(bank, VRAM_PAGE_ABG + ofs * 8);
417
+					break;
418
+				case 2: // arm7
419
+					vramConfiguration.banks[bank].purpose = VramConfiguration::ARM7;
420
+					if (bank == 2)
421
+						T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 1);
422
+					if (bank == 3)
423
+						T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 2);
424
+					switch (ofs)
425
+					{
426
+						case 0:
427
+						case 1:
428
+							vram_arm7_map[ofs] = vram_bank_info[bank].page_addr;
429
+					}
430
+					break;
431
+				case 3: // texture
432
+					vramConfiguration.banks[bank].purpose = VramConfiguration::TEX;
433
+					MMU.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
434
+					break;
435
+				case 4: // BGB or BOBJ
436
+					if (bank == VRAM_BANK_C) 
437
+					{
438
+						vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
439
+						MMU_vram_arm9(bank, VRAM_PAGE_BBG); // BBG
440
+					}
441
+					else
442
+					{
443
+						vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJ;
444
+						MMU_vram_arm9(bank, VRAM_PAGE_BOBJ); // BOBJ
445
+					}
446
+					break;
447
+				default:
448
+					goto unsupported_mst;
537 449
 			}
538 450
 			break;
539 451
 
540 452
 		case VRAM_BANK_E:
541 453
 			mst = VRAMBankCnt & 7;
542
-			//if(((VRAMBankCnt>>3)&3) != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
543
-			switch(mst) {
544
-			case 0: //LCDC
545
-				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
546
-				MMU_vram_lcdc(bank);
547
-				break;
548
-			case 1: //ABG
549
-				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
550
-				MMU_vram_arm9(bank,VRAM_PAGE_ABG);
551
-				break;
552
-			case 2: //AOBJ
553
-				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
554
-				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ);
555
-				break;
556
-			case 3: //texture palette
557
-				vramConfiguration.banks[bank].purpose = VramConfiguration::TEXPAL;
558
-				MMU.texInfo.texPalSlot[0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
559
-				MMU.texInfo.texPalSlot[1] = MMU_vram_physical(vram_bank_info[bank].page_addr+1);
560
-				MMU.texInfo.texPalSlot[2] = MMU_vram_physical(vram_bank_info[bank].page_addr+2);
561
-				MMU.texInfo.texPalSlot[3] = MMU_vram_physical(vram_bank_info[bank].page_addr+3);
562
-				break;
563
-			case 4: //A BG extended palette
564
-				vramConfiguration.banks[bank].purpose = VramConfiguration::ABGEXTPAL;
565
-				MMU.ExtPal[0][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
566
-				MMU.ExtPal[0][1] = MMU.ExtPal[0][0]/* + ADDRESS_STEP_8KB*/;
567
-				MMU.ExtPal[0][2] = MMU.ExtPal[0][1]/* + ADDRESS_STEP_8KB*/;
568
-				MMU.ExtPal[0][3] = MMU.ExtPal[0][2]/* + ADDRESS_STEP_8KB*/;
569
-				break;
570
-			default: goto unsupported_mst;
454
+			switch (mst)
455
+			{
456
+				case 0: // LCDC
457
+					vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
458
+					MMU_vram_lcdc(bank);
459
+					break;
460
+				case 1: // ABG
461
+					vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
462
+					MMU_vram_arm9(bank, VRAM_PAGE_ABG);
463
+					break;
464
+				case 2: // AOBJ
465
+					vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
466
+					MMU_vram_arm9(bank, VRAM_PAGE_AOBJ);
467
+					break;
468
+				case 3: // texture palette
469
+					vramConfiguration.banks[bank].purpose = VramConfiguration::TEXPAL;
470
+					MMU.texInfo.texPalSlot[0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
471
+					MMU.texInfo.texPalSlot[1] = MMU_vram_physical(vram_bank_info[bank].page_addr + 1);
472
+					MMU.texInfo.texPalSlot[2] = MMU_vram_physical(vram_bank_info[bank].page_addr + 2);
473
+					MMU.texInfo.texPalSlot[3] = MMU_vram_physical(vram_bank_info[bank].page_addr + 3);
474
+					break;
475
+				case 4: // ABG extended palette
476
+					vramConfiguration.banks[bank].purpose = VramConfiguration::ABGEXTPAL;
477
+					MMU.ExtPal[0][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
478
+					MMU.ExtPal[0][1] = MMU.ExtPal[0][0]/* + ADDRESS_STEP_8KB*/;
479
+					MMU.ExtPal[0][2] = MMU.ExtPal[0][1]/* + ADDRESS_STEP_8KB*/;
480
+					MMU.ExtPal[0][3] = MMU.ExtPal[0][2]/* + ADDRESS_STEP_8KB*/;
481
+					break;
482
+				default:
483
+					goto unsupported_mst;
571 484
 			}
572 485
 			break;
573 486
 
574 487
 		case VRAM_BANK_F:
575
-		case VRAM_BANK_G: {
488
+		case VRAM_BANK_G:
489
+		{
576 490
 			mst = VRAMBankCnt & 7;
577
-			ofs = (VRAMBankCnt>>3) & 3;
578
-			const int pageofslut[] = {0,1,4,5};
579
-			const int pageofs = pageofslut[ofs];
580
-			switch(mst)
491
+			ofs = (VRAMBankCnt >> 3) & 3;
492
+			const int pageofslut[] = {0, 1, 4, 5};
493
+			int pageofs = pageofslut[ofs];
494
+			switch (mst)
581 495
 			{
582
-			case 0: //LCDC
583
-				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
584
-				MMU_vram_lcdc(bank);
585
-				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
586
-				break;
587
-			case 1: //ABG
588
-				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
589
-				MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs);
590
-				MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs+2); //unexpected mirroring (required by spyro eternal night)
591
-				break;
592
-			case 2: //AOBJ
593
-				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
594
-				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+pageofs);
595
-				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+pageofs+2); //unexpected mirroring - I have no proof, but it is inferred from the ABG above
596
-				break;
597
-			case 3: //texture palette
598
-				vramConfiguration.banks[bank].purpose = VramConfiguration::TEXPAL;
599
-				MMU.texInfo.texPalSlot[pageofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
600
-				break;
601
-			case 4: //A BG extended palette
602
-				switch(ofs) {
603
-				case 0:
604
-				case 1:
605
-					vramConfiguration.banks[bank].purpose = VramConfiguration::ABGEXTPAL;
606
-					MMU.ExtPal[0][ofs*2] = MMU_vram_physical(vram_bank_info[bank].page_addr);
607
-					MMU.ExtPal[0][ofs*2+1] = MMU.ExtPal[0][ofs*2]/* + ADDRESS_STEP_8KB*/;
496
+				case 0: // LCDC
497
+					vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
498
+					MMU_vram_lcdc(bank);
608 499
 					break;
609
-				default:
610
-					vramConfiguration.banks[bank].purpose = VramConfiguration::INVALID;
611
-					//PROGINFO("Unsupported ofs setting %d for engine A bgextpal vram bank %c\n", ofs, 'A'+bank);
500
+				case 1: // ABG
501
+					vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
502
+					MMU_vram_arm9(bank, VRAM_PAGE_ABG + pageofs);
503
+					MMU_vram_arm9(bank, VRAM_PAGE_ABG + pageofs + 2); // unexpected mirroring (required by spyro eternal night)
612 504
 					break;
613
-				}
614
-				break;
615
-			case 5: //A OBJ extended palette
616
-				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJEXTPAL;
617
-				MMU.ObjExtPal[0][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
618
-				MMU.ObjExtPal[0][1] = MMU.ObjExtPal[0][1]/* + ADDRESS_STEP_8KB*/;
619
-				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
620
-				break;
621
-			default: goto unsupported_mst;
505
+				case 2: // AOBJ
506
+					vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
507
+					MMU_vram_arm9(bank, VRAM_PAGE_AOBJ + pageofs);
508
+					MMU_vram_arm9(bank, VRAM_PAGE_AOBJ + pageofs + 2); // unexpected mirroring - I have no proof, but it is inferred from the ABG above
509
+					break;
510
+				case 3: // texture palette
511
+					vramConfiguration.banks[bank].purpose = VramConfiguration::TEXPAL;
512
+					MMU.texInfo.texPalSlot[pageofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
513
+					break;
514
+				case 4: // ABG extended palette
515
+					switch (ofs)
516
+					{
517
+						case 0:
518
+						case 1:
519
+							vramConfiguration.banks[bank].purpose = VramConfiguration::ABGEXTPAL;
520
+							MMU.ExtPal[0][ofs * 2] = MMU_vram_physical(vram_bank_info[bank].page_addr);
521
+							MMU.ExtPal[0][ofs * 2 + 1] = MMU.ExtPal[0][ofs * 2]/* + ADDRESS_STEP_8KB*/;
522
+							break;
523
+						default:
524
+							vramConfiguration.banks[bank].purpose = VramConfiguration::INVALID;
525
+					}
526
+					break;
527
+				case 5: // AOBJ extended palette
528
+					vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJEXTPAL;
529
+					MMU.ObjExtPal[0][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
530
+					MMU.ObjExtPal[0][1] = MMU.ObjExtPal[0][1]/* + ADDRESS_STEP_8KB*/;
531
+					break;
532
+				default:
533
+					goto unsupported_mst;
622 534
 			}
623 535
 			break;
624 536
 		}
625 537
 
626 538
 		case VRAM_BANK_H:
627 539
 			mst = VRAMBankCnt & 3;
628
-			//if(((VRAMBankCnt>>3)&3) != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
629
-			switch(mst)
540
+			switch (mst)
630 541
 			{
631
-			case 0: //LCDC
632
-				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
633
-				MMU_vram_lcdc(bank);
634
-				break;
635
-			case 1: //BBG
636
-				vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
637
-				MMU_vram_arm9(bank,VRAM_PAGE_BBG);
638
-				MMU_vram_arm9(bank,VRAM_PAGE_BBG + 4); //unexpected mirroring
639
-				break;
640
-			case 2: //B BG extended palette
641
-				vramConfiguration.banks[bank].purpose = VramConfiguration::BBGEXTPAL;
642
-				MMU.ExtPal[1][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
643
-				MMU.ExtPal[1][1] = MMU.ExtPal[1][0]/* + ADDRESS_STEP_8KB*/;
644
-				MMU.ExtPal[1][2] = MMU.ExtPal[1][1]/* + ADDRESS_STEP_8KB*/;
645
-				MMU.ExtPal[1][3] = MMU.ExtPal[1][2]/* + ADDRESS_STEP_8KB*/;
646
-				break;
647
-			default: goto unsupported_mst;
542
+				case 0: // LCDC
543
+					vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
544
+					MMU_vram_lcdc(bank);
545
+					break;
546
+				case 1: // BBG
547
+					vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
548
+					MMU_vram_arm9(bank, VRAM_PAGE_BBG);
549
+					MMU_vram_arm9(bank, VRAM_PAGE_BBG + 4); // unexpected mirroring
550
+					break;
551
+				case 2: // BBG extended palette
552
+					vramConfiguration.banks[bank].purpose = VramConfiguration::BBGEXTPAL;
553
+					MMU.ExtPal[1][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
554
+					MMU.ExtPal[1][1] = MMU.ExtPal[1][0]/* + ADDRESS_STEP_8KB*/;
555
+					MMU.ExtPal[1][2] = MMU.ExtPal[1][1]/* + ADDRESS_STEP_8KB*/;
556
+					MMU.ExtPal[1][3] = MMU.ExtPal[1][2]/* + ADDRESS_STEP_8KB*/;
557
+					break;
558
+				default:
559
+					goto unsupported_mst;
648 560
 			}
649 561
 			break;
650 562
 
651 563
 		case VRAM_BANK_I:
652 564
 			mst = VRAMBankCnt & 3;
653
-			//if(((VRAMBankCnt>>3)&3) != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
654
-			switch(mst)
565
+			switch (mst)
655 566
 			{
656
-			case 0: //LCDC
657
-				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
658
-				MMU_vram_lcdc(bank);
659
-				break;
660
-			case 1: //BBG
661
-				vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
662
-				MMU_vram_arm9(bank,VRAM_PAGE_BBG+2);
663
-				MMU_vram_arm9(bank,VRAM_PAGE_BBG+3); //unexpected mirroring
664
-				break;
665
-			case 2: //BOBJ
666
-				vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJ;
667
-				MMU_vram_arm9(bank,VRAM_PAGE_BOBJ);
668
-				MMU_vram_arm9(bank,VRAM_PAGE_BOBJ+1); //FF3 end scene (lens flare sprite) needs this as it renders a sprite off the end of the 16KB and back around
669
-				break;
670
-			case 3: //B OBJ extended palette
671
-				vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJEXTPAL;
672
-				MMU.ObjExtPal[1][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
673
-				MMU.ObjExtPal[1][1] = MMU.ObjExtPal[1][1]/* + ADDRESS_STEP_8KB*/;
674
-				break;
675
-			default: goto unsupported_mst;
567
+				case 0: // LCDC
568
+					vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
569
+					MMU_vram_lcdc(bank);
570
+					break;
571
+				case 1: // BBG
572
+					vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
573
+					MMU_vram_arm9(bank, VRAM_PAGE_BBG + 2);
574
+					MMU_vram_arm9(bank, VRAM_PAGE_BBG + 3); // unexpected mirroring
575
+					break;
576
+				case 2: // BOBJ
577
+					vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJ;
578
+					MMU_vram_arm9(bank, VRAM_PAGE_BOBJ);
579
+					MMU_vram_arm9(bank, VRAM_PAGE_BOBJ + 1); // FF3 end scene (lens flare sprite) needs this as it renders a sprite off the end of the 16KB and back around
580
+					break;
581
+				case 3: // BOBJ extended palette
582
+					vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJEXTPAL;
583
+					MMU.ObjExtPal[1][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
584
+					MMU.ObjExtPal[1][1] = MMU.ObjExtPal[1][1]/* + ADDRESS_STEP_8KB*/;
585
+					break;
586
+				default:
587
+					goto unsupported_mst;
676 588
 			}
677 589
 			break;
678
-
679
-
680
-	} //switch(bank)
590
+	} // switch(bank)
681 591
 
682 592
 	vramConfiguration.banks[bank].ofs = ofs;
683 593
 
... ...
@@ -685,7 +595,6 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
685 595
 
686 596
 unsupported_mst:
687 597
 	vramConfiguration.banks[bank].purpose = VramConfiguration::INVALID;
688
-	//PROGINFO("Unsupported mst setting %d for vram bank %c\n", mst, 'A'+bank);
689 598
 }
690 599
 
691 600
 void MMU_VRAM_unmap_all()
... ...
@@ -695,12 +604,12 @@ void MMU_VRAM_unmap_all()
695 604
 	vram_arm7_map[0] = VRAM_PAGE_UNMAPPED;
696 605
 	vram_arm7_map[1] = VRAM_PAGE_UNMAPPED;
697 606
 
698
-	for(int i=0;i<VRAM_LCDC_PAGES;i++)
607
+	for (int i = 0; i < VRAM_LCDC_PAGES; ++i)
699 608
 		vram_lcdc_map[i] = VRAM_PAGE_UNMAPPED;
700
-	for(int i=0;i<VRAM_ARM9_PAGES;i++)
609
+	for (int i = 0; i < VRAM_ARM9_PAGES; ++i)
701 610
 		vram_arm9_map[i] = VRAM_PAGE_UNMAPPED;
702 611
 
703
-	for (int i = 0; i < 4; i++)
612
+	for (int i = 0; i < 4; ++i)
704 613
 	{
705 614
 		MMU.ExtPal[0][i] = MMU.blank_memory;
706 615
 		MMU.ExtPal[1][i] = MMU.blank_memory;
... ...
@@ -711,213 +620,161 @@ void MMU_VRAM_unmap_all()
711 620
 	MMU.ObjExtPal[1][0] = MMU.blank_memory;
712 621
 	MMU.ObjExtPal[1][1] = MMU.blank_memory;
713 622
 
714
-	for(int i=0;i<6;i++)
623
+	for (int i = 0; i < 6; ++i)
715 624
 		MMU.texInfo.texPalSlot[i] = MMU.blank_memory;
716 625
 
717
-	for(int i=0;i<4;i++)
626
+	for (int i = 0; i < 4; ++i)
718 627
 		MMU.texInfo.textureSlotAddr[i] = MMU.blank_memory;
719 628
 }
720 629
 
721 630
 static inline void MMU_VRAMmapControl(uint8_t block, uint8_t VRAMBankCnt)
722 631
 {
723
-	//dont handle wram mappings in here
724
-	if(block == 7) {
725
-		//wram
632
+	// handle WRAM, first of all
633
+	if (block == 7)
634
+	{
635
+		MMU.WRAMCNT = VRAMBankCnt & 3;
726 636
 		return;
727 637
 	}
728 638
 
729
-	//first, save the texture info so we can check it for changes and trigger purges of the texcache
639
+	//f irst, save the texture info so we can check it for changes and trigger purges of the texcache
730 640
 	MMU_struct::TextureInfo oldTexInfo = MMU.texInfo;
731 641
 
732
-	//unmap everything
642
+	// unmap everything
733 643
 	MMU_VRAM_unmap_all();
734 644
 
735
-	//unmap VRAM_BANK_C and VRAM_BANK_D from arm7. theyll get mapped again in a moment if necessary
645
+	// unmap VRAM_BANK_C and VRAM_BANK_D from arm7. theyll get mapped again in a moment if necessary
736 646
 	T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, 0);
737 647
 
738
-	//write the new value to the reg
648
+	// write the new value to the reg
739 649
 	T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x240 + block, VRAMBankCnt);
740 650
 
741
-	//refresh all bank settings
742
-	//these are enumerated so that we can tune the order they get applied
743
-	//in order to emulate prioritization rules for memory regions
744
-	//with multiple banks mapped.
745
-	//We're probably still not mapping things 100% correctly, but this helped us get closer:
746
-	//goblet of fire "care of magical creatures" maps I and D to BOBJ (the I is an accident)
747
-	//and requires A to override it.
748
-	//This may create other bugs....
651
+	// refresh all bank settings
652
+	// zero XX-XX-200X (long before jun 2012)
653
+	// these are enumerated so that we can tune the order they get applied
654
+	// in order to emulate prioritization rules for memory regions
655
+	// with multiple banks mapped.
656
+	// We're probably still not mapping things 100% correctly, but this helped us get closer:
657
+	// goblet of fire "care of magical creatures" maps I and D to BOBJ (the I is an accident)
658
+	// and requires A to override it.
659
+	// This may create other bugs....
749 660
 	MMU_VRAMmapRefreshBank(VRAM_BANK_I);
750 661
 	MMU_VRAMmapRefreshBank(VRAM_BANK_H);
751 662
 	MMU_VRAMmapRefreshBank(VRAM_BANK_G);
752 663
 	MMU_VRAMmapRefreshBank(VRAM_BANK_F);
753 664
 	MMU_VRAMmapRefreshBank(VRAM_BANK_E);
754
-	MMU_VRAMmapRefreshBank(VRAM_BANK_D);
755
-	MMU_VRAMmapRefreshBank(VRAM_BANK_C);
756
-	MMU_VRAMmapRefreshBank(VRAM_BANK_B);
665
+	// zero 21-jun-2012
666
+	// tomwi's streaming music demo sets A and D to ABG (the A is an accident).
667
+	// in this case, D should get priority. 
668
+	// this is somewhat risky. will it break other things?
757 669
 	MMU_VRAMmapRefreshBank(VRAM_BANK_A);
670
+	MMU_VRAMmapRefreshBank(VRAM_BANK_B);
671
+	MMU_VRAMmapRefreshBank(VRAM_BANK_C);
672
+	MMU_VRAMmapRefreshBank(VRAM_BANK_D);
758 673
 
759 674
 	//printf(vramConfiguration.describe().c_str());
760 675
 	//printf("vram remapped at vcount=%d\n",nds.VCount);
761 676
 
762
-	//if texInfo changed, trigger notifications
763
-	if(memcmp(&oldTexInfo,&MMU.texInfo,sizeof(MMU_struct::TextureInfo)))
764
-	{
765
-		//if(!nds.isIn3dVblank())
766
-	//		PROGINFO("Changing texture or texture palette mappings outside of 3d vblank\n");
767
-		//gpu3D->NDS_3D_VramReconfigureSignal();
768
-	}
769
-
770
-	//-------------------------------
771
-	//set up arm9 mirrorings
772
-	//these are probably not entirely accurate. more study will be necessary.
773
-	//in general, we find that it is not uncommon at all for games to accidentally do this.
677
+	// -------------------------------
678
+	// set up arm9 mirrorings
679
+	// these are probably not entirely accurate. more study will be necessary.
680
+	// in general, we find that it is not uncommon at all for games to accidentally do this.
774 681
 	//
775
-	//being able to easily do these experiments was one of the primary motivations for this remake of the vram mapping system
776
-
777
-	//see the "unexpected mirroring" comments above for some more mirroring
778
-	//so far "unexpected mirrorings" are tested by combining these games:
779
-	//despereaux - storybook subtitles
780
-	//NSMB - world map sub screen
781
-	//drill spirits EU - mission select (just for control purposes, as it doesnt use H or I)
782
-	//...
783
-	//note that the "unexpected mirroring" items above may at some point rely on being executed in a certain order.
784
-	//(sequentially A..I)
785
-
786
-	const int types[] = {VRAM_PAGE_ABG,VRAM_PAGE_BBG,VRAM_PAGE_AOBJ,VRAM_PAGE_BOBJ};
787
-	const int sizes[] = {32,8,16,8};
788
-	for(int t=0;t<4;t++)
789
-	{
790
-		//the idea here is to pad out the mirrored space with copies of the mappable area,
791
-		//without respect to what is mapped within that mappable area.
792
-		//we hope that this is correct in all cases
793
-		//required for driller spirits in mission select (mapping is simple A,B,C,D to each purpose)
794
-		const int size = sizes[t];
795
-		const int mask = size-1;
796
-		const int type = types[t];
797
-		for(int i=size;i<128;i++)
682
+	// being able to easily do these experiments was one of the primary motivations for this remake of the vram mapping system
683
+
684
+	// see the "unexpected mirroring" comments above for some more mirroring
685
+	// so far "unexpected mirrorings" are tested by combining these games:
686
+	// despereaux - storybook subtitles
687
+	// NSMB - world map sub screen
688
+	// drill spirits EU - mission select (just for control purposes, as it doesnt use H or I)
689
+	// ...
690
+	// note that the "unexpected mirroring" items above may at some point rely on being executed in a certain order.
691
+	// (sequentially A..I)
692
+
693
+	const int types[] = { VRAM_PAGE_ABG, VRAM_PAGE_BBG, VRAM_PAGE_AOBJ, VRAM_PAGE_BOBJ };
694
+	const int sizes[] = {32, 8, 16, 8};
695
+	for (int t = 0; t < 4; ++t)
696
+	{
697
+		// the idea here is to pad out the mirrored space with copies of the mappable area,
698
+		// without respect to what is mapped within that mappable area.
699
+		// we hope that this is correct in all cases
700
+		// required for driller spirits in mission select (mapping is simple A,B,C,D to each purpose)
701
+		int size = sizes[t];
702
+		int mask = size - 1;
703
+		int type = types[t];
704
+		for (int i = size; i < 128; ++i)
798 705
 		{
799
-			const int page = type + i;
800
-			vram_arm9_map[page] = vram_arm9_map[type+(i&mask)];
706
+			int page = type + i;
707
+			vram_arm9_map[page] = vram_arm9_map[type + (i & mask)];
801 708
 		}
802
-
803
-		//attempt #1: screen corruption in drill spirits EU
804
-		//it seems like these shouldnt pad out 128K banks (space beyond those should have remained unmapped)
805
-		//int mirrorMask = -1;
806
-		//int type = types[t];
807
-		////if(type==VRAM_PAGE_BOBJ) continue;
808
-		//if(type==VRAM_PAGE_AOBJ) continue;
809
-		//for(int i=0;i<128;i++)
810
-		//{
811
-		//	int page = type + i;
812
-		//	if(vram_arm9_map[page] == VRAM_PAGE_UNMAPPED)
813
-		//	{
814
-		//		if(i==0) break; //can't mirror anything if theres nothing mapped!
815
-		//		if(mirrorMask == -1)
816
-		//			mirrorMask = i-1;
817
-		//		vram_arm9_map[page] = vram_arm9_map[type+(i&mirrorMask)];
818
-		//	}
819
-		//}
820 709
 	}
821
-
822
-	//-------------------------------
823 710
 }
824 711
 
825 712
 //////////////////////////////////////////////////////////////
826 713
 //end vram
827 714
 //////////////////////////////////////////////////////////////
828 715
 
829
-
830
-
831
-void MMU_Init() {
832
-	//LOG("MMU init\n");
833
-
716
+void MMU_Init()
717
+{
834 718
 	memset(&MMU, 0, sizeof(MMU_struct));
835 719
 
836 720
 	MMU.CART_ROM = MMU.UNUSED_RAM;
837 721
 
838
-	//MMU.DTCMRegion = 0x027C0000;
839
-	//even though apps may change dtcm immediately upon startup, this is the correct hardware starting value:
722
+	// even though apps may change dtcm immediately upon startup, this is the correct hardware starting value:
840 723
 	MMU.DTCMRegion = 0x08000000;
841 724
 	MMU.ITCMRegion = 0x00000000;
842 725
 
843 726
 	IPC_FIFOinit(ARMCPU_ARM9);
844 727
 	IPC_FIFOinit(ARMCPU_ARM7);
845
-	//GFX_PIPEclear();
846
-	//GFX_FIFOclear();
847
-	//DISP_FIFOinit();
848 728
 	new(&MMU_new) MMU_struct_new;
849 729
 
850
-	mc_init(&MMU.fw, MC_TYPE_FLASH);  /* init fw device */
730
+	mc_init(&MMU.fw, MC_TYPE_FLASH); /* init fw device */
851 731
 	mc_alloc(&MMU.fw, NDS_FW_SIZE_V1);
852
-	MMU.fw.fp = NULL;
732
+	MMU.fw.fp = nullptr;
853 733
 	MMU.fw.isFirmware = true;
854
-
855
-	// Init Backup Memory device, this should really be done when the rom is loaded
856
-	//mc_init(&MMU.bupmem, MC_TYPE_AUTODETECT);
857
-	//mc_alloc(&MMU.bupmem, 1);
858
-	//MMU.bupmem.fp = NULL;
859
-	//rtcInit();
860
-	//addonsInit();
861
-	//slot1Init();
862
-	/*if(Mic_Init() == false)
863
-		INFO("Microphone init failed.\n");
864
-	else
865
-		INFO("Microphone successfully inited.\n");*/
866 734
 }
867 735
 
868
-void MMU_DeInit() {
869
-	//LOG("MMU deinit\n");
870
-	/*if (MMU.fw.fp)
871
-		fclose(MMU.fw.fp);*/
736
+void MMU_DeInit()
737
+{
872 738
 	mc_free(&MMU.fw);
873
-	//if (MMU.bupmem.fp)
874
-	//	fclose(MMU.bupmem.fp);
875
-	//mc_free(&MMU.bupmem);
876
-	//addonsClose();
877
-	//slot1Close();
878
-	//Mic_DeInit();
879 739
 }
880 740
 
881 741
 void MMU_Reset()
882 742
 {
883 743
 	memset(MMU.ARM9_DTCM, 0, sizeof(MMU.ARM9_DTCM));
884 744
 	memset(MMU.ARM9_ITCM, 0, sizeof(MMU.ARM9_ITCM));
885
-	memset(MMU.ARM9_LCD,  0, sizeof(MMU.ARM9_LCD));
886
-	memset(MMU.ARM9_OAM,  0, sizeof(MMU.ARM9_OAM));
887
-	memset(MMU.ARM9_REG,  0, sizeof(MMU.ARM9_REG));
745
+	memset(MMU.ARM9_LCD, 0, sizeof(MMU.ARM9_LCD));
746
+	memset(MMU.ARM9_OAM, 0, sizeof(MMU.ARM9_OAM));
747
+	memset(MMU.ARM9_REG, 0, sizeof(MMU.ARM9_REG));
888 748
 	memset(MMU.ARM9_VMEM, 0, sizeof(MMU.ARM9_VMEM));
889
-	memset(MMU.MAIN_MEM,  0, sizeof(MMU.MAIN_MEM));
749
+	memset(MMU.MAIN_MEM, 0, sizeof(MMU.MAIN_MEM));
890 750
 
891
-	memset(MMU.blank_memory,  0, sizeof(MMU.blank_memory));
892
-	memset(MMU.UNUSED_RAM,    0, sizeof(MMU.UNUSED_RAM));
893
-	memset(MMU.MORE_UNUSED_RAM,    0, sizeof(MMU.UNUSED_RAM));
751
+	memset(MMU.blank_memory, 0, sizeof(MMU.blank_memory));
752
+	memset(MMU.UNUSED_RAM, 0, sizeof(MMU.UNUSED_RAM));
753
+	memset(MMU.MORE_UNUSED_RAM, 0, sizeof(MMU.UNUSED_RAM));
894 754
 
895
-	memset(MMU.ARM7_ERAM,     0, sizeof(MMU.ARM7_ERAM));
896
-	memset(MMU.ARM7_REG,      0, sizeof(MMU.ARM7_REG));
897
-	memset(MMU.ARM7_WIRAM,	  0, sizeof(MMU.ARM7_WIRAM));
898
-	memset(MMU.SWIRAM,	  0, sizeof(MMU.SWIRAM));
755
+	memset(MMU.ARM7_ERAM, 0, sizeof(MMU.ARM7_ERAM));
756
+	memset(MMU.ARM7_REG, 0, sizeof(MMU.ARM7_REG));
757
+	memset(MMU.ARM7_WIRAM, 0, sizeof(MMU.ARM7_WIRAM));
758
+	memset(MMU.SWIRAM, 0, sizeof(MMU.SWIRAM));
899 759
 
900 760
 	IPC_FIFOinit(ARMCPU_ARM9);
901 761
 	IPC_FIFOinit(ARMCPU_ARM7);
902
-	//GFX_PIPEclear();
903
-	//GFX_FIFOclear();
904
-	//DISP_FIFOinit();
905 762
 
906 763
 	MMU.DTCMRegion = 0x027C0000;
907 764
 	MMU.ITCMRegion = 0x00000000;
908 765
 
909
-	memset(MMU.timer,         0, sizeof(uint16_t) * 2 * 4);
910
-	memset(MMU.timerMODE,     0, sizeof(int32_t) * 2 * 4);
911
-	memset(MMU.timerON,       0, sizeof(uint32_t) * 2 * 4);
912
-	memset(MMU.timerRUN,      0, sizeof(uint32_t) * 2 * 4);
913
-	memset(MMU.timerReload,   0, sizeof(uint16_t) * 2 * 4);
766
+	memset(MMU.timer, 0, sizeof(uint16_t) * 8);
767
+	memset(MMU.timerMODE, 0, sizeof(int32_t) * 8);
768
+	memset(MMU.timerON, 0, sizeof(uint32_t) * 8);
769
+	memset(MMU.timerRUN, 0, sizeof(uint32_t) * 8);
770
+	memset(MMU.timerReload, 0, sizeof(uint16_t) * 8);
914 771
 
915
-	memset(MMU.reg_IME,       0, sizeof(uint32_t) * 2);
916
-	memset(MMU.reg_IE,        0, sizeof(uint32_t) * 2);
917
-	memset(MMU.reg_IF_bits,   0, sizeof(uint32_t) * 2);
918
-	memset(MMU.reg_IF_pending,   0, sizeof(uint32_t) * 2);
772
+	memset(MMU.reg_IME, 0, sizeof(uint32_t) * 2);
773
+	memset(MMU.reg_IE, 0, sizeof(uint32_t) * 2);
774
+	memset(MMU.reg_IF_bits, 0, sizeof(uint32_t) * 2);
775
+	memset(MMU.reg_IF_pending, 0, sizeof(uint32_t) * 2);
919 776
 
920
-	memset(MMU.dscard,        0, sizeof(nds_dscard) * 2);
777
+	memset(MMU.dscard, 0, sizeof(nds_dscard) * 2);
921 778
 
922 779
 	MMU.divRunning = 0;
923 780
 	MMU.divResult = 0;
... ...
@@ -931,12 +788,11 @@ void MMU_Reset()
931 788
 	MMU.SPI_CNT = 0;
932 789
 	MMU.AUX_SPI_CNT = 0;
933 790
 
791
+	MMU.WRAMCNT = 0;
792
+
934 793
 	// Enable the sound speakers
935 794
 	T1WriteWord(MMU.ARM7_REG, 0x304, 0x0001);
936 795
 
937
-	//MainScreen.offset = 0;
938
-	//SubScreen.offset  = 192;
939
-
940 796
 	MMU_VRAM_unmap_all();
941 797
 
942 798
 	MMU.powerMan_CntReg = 0x00;
... ...
@@ -946,12 +802,7 @@ void MMU_Reset()
946 802
 	MMU.powerMan_Reg[2] = 0x01;
947 803
 	MMU.powerMan_Reg[3] = 0x00;
948 804
 
949
-	//rtcInit();
950 805
 	partie = 1;
951
-	//addonsReset();
952
-	//slot1Reset();
953
-	//Mic_Reset();
954
-	//MMU.gfx3dCycles = 0;
955 806
 
956 807
 	memset(MMU.dscard[ARMCPU_ARM9].command, 0, 8);
957 808
 	MMU.dscard[ARMCPU_ARM9].address = 0;
... ...
@@ -963,18 +814,12 @@ void MMU_Reset()
963 814
 	MMU.dscard[ARMCPU_ARM7].transfer_count = 0;
964 815
 	MMU.dscard[ARMCPU_ARM7].mode = CardMode_Normal;
965 816
 
966
-	//HACK!!!
967
-	//until we improve all our session tracking stuff, we need to save the backup memory filename
817
+	// HACK!!!
818
+	// until we improve all our session tracking stuff, we need to save the backup memory filename
968 819
 	std::string bleh = MMU_new.backupDevice.getFilename();
969 820
 	BackupDevice tempBackupDevice;
970
-	//bool bleh2 = MMU_new.backupDevice.isMovieMode;
971
-	//if(bleh2) tempBackupDevice = MMU_new.backupDevice;
972 821
 	reconstruct(&MMU_new);
973
-	/*if(bleh2) {
974
-		MMU_new.backupDevice = tempBackupDevice;
975
-		MMU_new.backupDevice.reset_hardware();
976
-	}
977
-	else*/ MMU_new.backupDevice.load_rom(bleh.c_str());
822
+	MMU_new.backupDevice.load_rom(bleh);
978 823
 
979 824
 	MMU_timing.arm7codeFetch.Reset();
980 825
 	MMU_timing.arm7dataFetch.Reset();
... ...
@@ -984,39 +829,47 @@ void MMU_Reset()
984 829
 	MMU_timing.arm9dataCache.Reset();
985 830
 }
986 831
 
987
-void SetupMMU(bool debugConsole, bool dsi) {
988
-	if(debugConsole) _MMU_MAIN_MEM_MASK = 0x7FFFFF;
989
-	else _MMU_MAIN_MEM_MASK = 0x3FFFFF;
990
-	if(dsi) _MMU_MAIN_MEM_MASK = 0xFFFFFF;
832
+void SetupMMU(bool debugConsole, bool dsi)
833
+{
834
+	if (debugConsole)
835
+		_MMU_MAIN_MEM_MASK = 0x7FFFFF;
836
+	else
837
+		_MMU_MAIN_MEM_MASK = 0x3FFFFF;
838
+	if (dsi)
839
+		_MMU_MAIN_MEM_MASK = 0xFFFFFF;
991 840
 	_MMU_MAIN_MEM_MASK16 = _MMU_MAIN_MEM_MASK & ~1;
992 841
 	_MMU_MAIN_MEM_MASK32 = _MMU_MAIN_MEM_MASK & ~3;
993 842
 }
994 843
 
995
-void MMU_setRom(uint8_t * rom, uint32_t)
844
+void MMU_setRom(uint8_t *rom, uint32_t)
996 845
 {
997 846
 	MMU.CART_ROM = rom;
998 847
 }
999 848
 
1000 849
 void MMU_unsetRom()
1001 850
 {
1002
-	MMU.CART_ROM=MMU.UNUSED_RAM;
851
+	MMU.CART_ROM = MMU.UNUSED_RAM;
1003 852
 }
1004 853
 
1005
-static void execsqrt() {
854
+static void execsqrt()
855
+{
1006 856
 	uint32_t ret;
1007 857
 	uint8_t mode = MMU_new.sqrt.mode;
1008 858
 	MMU_new.sqrt.busy = 1;
1009 859
 
1010
-	if (mode) {
860
+	if (mode)
861
+	{
1011 862
 		uint64_t v = T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B8);
1012
-		ret = (uint32_t)isqrt(v);
1013
-	} else {
863
+		ret = static_cast<uint32_t>(isqrt(v));
864
+	}
865
+	else
866
+	{
1014 867
 		uint32_t v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B8);
1015
-		ret = (uint32_t)isqrt(v);
868
+		ret = static_cast<uint32_t>(isqrt(v));
1016 869
 	}
1017 870
 
1018
-	//clear the result while the sqrt unit is busy
1019
-	//todo - is this right? is it reasonable?
871
+	// clear the result while the sqrt unit is busy
872
+	// todo - is this right? is it reasonable?
1020 873
 	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B4, 0);
1021 874
 
1022 875
 	MMU.sqrtCycles = nds_timer + 26;
... ...
@@ -1025,42 +878,41 @@ static void execsqrt() {
1025 878
 	NDS_Reschedule();
1026 879
 }
1027 880
 
1028
-static void execdiv() {
1029
-
1030
-	int64_t num,den;
1031
-	int64_t res,mod;
881
+static void execdiv()
882
+{
883
+	int64_t num, den;
884
+	int64_t res, mod;
1032 885
 	uint8_t mode = MMU_new.div.mode;
1033 886
 	MMU_new.div.busy = 1;
1034 887
 	MMU_new.div.div0 = 0;
1035 888
 
1036
-	switch(mode)
889
+	switch (mode)
1037 890
 	{
1038
-	case 0:	// 32/32
1039
-		num = (int64_t) (int32_t) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
1040
-		den = (int64_t) (int32_t) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
1041
-		MMU.divCycles = nds_timer + 36;
1042
-		break;
1043
-	case 1:	// 64/32
1044
-	case 3: //gbatek says this is same as mode 1
1045
-		num = (int64_t) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
1046
-		den = (int64_t) (int32_t) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
1047
-		MMU.divCycles = nds_timer + 68;
1048
-		break;
1049
-	case 2:	// 64/64
1050
-	default:
1051
-		num = (int64_t) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
1052
-		den = (int64_t) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
1053
-		MMU.divCycles = nds_timer + 68;
1054
-		break;
891
+		case 0: // 32/32
892
+			num = static_cast<int64_t>(static_cast<int32_t>(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290)));
893
+			den = static_cast<int64_t>(static_cast<int32_t>(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298)));
894
+			MMU.divCycles = nds_timer + 36;
895
+			break;
896
+		case 1: // 64/32
897
+		case 3: //gbatek says this is same as mode 1
898
+			num = static_cast<int64_t>(T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290));
899
+			den = static_cast<int64_t>(static_cast<int32_t>(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298)));
900
+			MMU.divCycles = nds_timer + 68;
901
+			break;
902
+		case 2: // 64/64
903
+		default:
904
+			num = static_cast<int64_t>(T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290));
905
+			den = static_cast<int64_t>(T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298));
906
+			MMU.divCycles = nds_timer + 68;
1055 907
 	}
1056 908
 
1057
-	if(den==0)
909
+	if (!den)
1058 910
 	{
1059
-		res = ((num < 0) ? 1 : -1);
911
+		res = num < 0 ? 1 : -1;
1060 912
 		mod = num;
1061 913
 
1062 914
 		// the DIV0 flag in DIVCNT is set only if the full 64bit DIV_DENOM value is zero, even in 32bit mode
1063
-		if ((uint64_t)T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298) == 0)
915
+		if (!static_cast<uint64_t>(T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298)))
1064 916
 			MMU_new.div.div0 = 1;
1065 917
 	}
1066 918
 	else
... ...
@@ -1069,10 +921,6 @@ static void execdiv() {
1069 921
 		mod = num % den;
1070 922
 	}
1071 923
 
1072
-	/*DIVLOG("DIV %08X%08X / %08X%08X = %08X%08X\r\n", (uint32_t)(num>>32), (uint32_t)num,
1073
-							(uint32_t)(den>>32), (uint32_t)den,
1074
-							(uint32_t)(res>>32), (uint32_t)res);*/
1075
-
1076 924
 	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A0, 0);
1077 925
 	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A4, 0);
1078 926
 	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A8, 0);
... ...
@@ -1086,39 +934,35 @@ static void execdiv() {
1086 934
 
1087 935
 DSI_TSC::DSI_TSC()
1088 936
 {
1089
-	for(unsigned i=0;i<ARRAY_SIZE(registers);i++)
1090
-		registers[i] = 0x00;
1091
-	reset_command();
937
+	for (unsigned i = 0; i < ARRAY_SIZE(this->registers); ++i)
938
+		this->registers[i] = 0x00;
939
+	this->reset_command();
1092 940
 }
1093 941
 
1094 942
 void DSI_TSC::reset_command()
1095 943
 {
1096
-	state = 0;
1097
-	readcount = 0;
1098
-	read_flag = 1;
944
+	this->state = 0;
945
+	this->readcount = 0;
946
+	this->read_flag = 1;
1099 947
 }
1100 948
 
1101 949
 uint16_t DSI_TSC::write16(uint16_t val)
1102 950
 {
1103 951
 	uint16_t ret;
1104
-	switch(state)
1105
-	{
1106
-	case 0:
1107
-		reg_selection = (val>>1)&0x7F;
1108
-		read_flag = val&1;
1109
-		state = 1;
1110
-		return read16();
1111
-	case 1:
1112
-		if(read_flag)
1113
-		{ }
1114
-		else
1115
-		{
1116
-			registers[reg_selection] = (uint8_t)val;
1117
-		}
1118
-		ret = read16();
1119
-		reg_selection++;
1120
-		reg_selection &= 0x7F;
1121
-		return ret;
952
+	switch (state)
953
+	{
954
+		case 0:
955
+			this->reg_selection = (val >> 1) & 0x7F;
956
+			this->read_flag = val & 1;
957
+			this->state = 1;
958
+			return this->read16();
959
+		case 1:
960
+			if (!this->read_flag)
961
+				this->registers[this->reg_selection] = static_cast<uint8_t>(val);
962
+			ret = this->read16();
963
+			++this->reg_selection;
964
+			this->reg_selection &= 0x7F;
965
+			return ret;
1122 966
 	}
1123 967
 	return 0;
1124 968
 }
... ...
@@ -1126,98 +970,37 @@ uint16_t DSI_TSC::write16(uint16_t val)
1126 970
 uint16_t DSI_TSC::read16()
1127 971
 {
1128 972
 	uint8_t page = registers[0];
1129
-	switch(page)
973
+	switch (page)
1130 974
 	{
1131
-	case 3: //page 3
1132
-		switch(reg_selection)
1133
-		{
1134
-		case 9:
1135
-			/*if(nds.isTouch)
1136
-				return 0;
1137
-			else */return 0x40;
1138
-			break;
1139
-		case 14:
1140
-			/*if(nds.isTouch)
1141
-				return 0;
1142
-			else */return 0x02;
1143
-			break;
1144
-		}
1145
-		break;
1146
-
1147
-	case 252: //page 252
1148
-		switch(reg_selection)
1149
-		{
1150
-		//high byte of X:
1151
-		/*case 1: case 3: case 5: case 7: case 9:
1152
-			return (nds.scr_touchX>>8)&0xFF;
1153
-
1154
-		//low byte of X:
1155
-		case 2: case 4: case 6: case 8: case 10:
1156
-			return nds.scr_touchX&0xFF;
1157
-
1158
-		//high byte of Y:
1159
-		case 11: case 13: case 15: case 17: case 19:
1160
-			return (nds.scr_touchY>>8)&0xFF;
1161
-
1162
-		//low byte of Y:
1163
-		case 12: case 14: case 16: case 18: case 20:
1164
-			return nds.scr_touchY&0xFF;*/
1165
-
1166
-		default:
1167
-			return 0xFF;
1168
-		}
1169
-		break;
1170
-	} //switch(page)
975
+		case 3: // page 3
976
+			switch (this->reg_selection)
977
+			{
978
+				case 9:
979
+					return 0x40;
980
+				case 14:
981
+					return 0x02;
982
+			}
983
+	} // switch(page)
1171 984
 
1172
-	//unknown page or register
985
+	// unknown page or register
1173 986
 	return 0xFF;
1174 987
 }
1175 988
 
1176
-/*bool DSI_TSC::save_state(EMUFILE* os)
1177
-{
1178
-	uint32_t version = 0;
1179
-	write32le(version,os);
1180
-
1181
-	write8le(reg_selection,os);
1182
-	write8le(read_flag,os);
1183
-	write32le(state,os);
1184
-	write32le(readcount,os);
1185
-	for(int i=0;i<ARRAY_SIZE(registers);i++)
1186
-		write8le(registers[i],os);
1187
-
1188
-	return true;
1189
-}*/
1190
-
1191
-/*bool DSI_TSC::load_state(EMUFILE* is)
1192
-{
1193
-	uint32_t version;
1194
-	read32le(&version,is);
1195
-
1196
-	read8le(&reg_selection,is);
1197
-	read8le(&read_flag,is);
1198
-	read32le(&state,is);
1199
-	read32le(&readcount,is);
1200
-	for(int i=0;i<ARRAY_SIZE(registers);i++)
1201
-		read8le(&registers[i],is);
1202
-
1203
-	return true;
1204
-}*/
1205
-
1206 989
 // TODO:
1207 990
 // NAND flash support (used in Made in Ore/WarioWare D.I.Y.)
1208
-template<int PROCNUM>
1209
-void FASTCALL MMU_writeToGCControl(uint32_t val)
991
+template<int PROCNUM> void FASTCALL MMU_writeToGCControl(uint32_t val)
1210 992
 {
1211
-	const int TEST_PROCNUM = PROCNUM;
1212
-	nds_dscard& card = MMU.dscard[TEST_PROCNUM];
993
+	int TEST_PROCNUM = PROCNUM;
994
+	nds_dscard &card = MMU.dscard[TEST_PROCNUM];
1213 995
 
1214 996
 	memcpy(&card.command[0], &MMU.MMU_MEM[TEST_PROCNUM][0x40][0x1A8], 8);
1215 997
 
1216 998
 	card.blocklen = 0;
1217
-	slot1_device.write32(PROCNUM,0xFFFFFFFF,val); //Special case for some flashcarts
1218
-	if(card.blocklen==0x01020304) return;
999
+	slot1_device.write32(PROCNUM, 0xFFFFFFFF, val); // Special case for some flashcarts
1000
+	if (card.blocklen == 0x01020304)
1001
+		return;
1219 1002
 
1220
-	if(!(val & 0x80000000))
1003
+	if (!(val & 0x80000000))
1221 1004
 	{
1222 1005
 		card.address = 0;
1223 1006
 		card.transfer_count = 0;
... ...
@@ -1227,21 +1010,20 @@ void FASTCALL MMU_writeToGCControl(uint32_t val)
1227 1010
 		return;
1228 1011
 	}
1229 1012
 
1230
-	uint32_t shift = (val>>24&7);
1231
-	if(shift == 7)
1013
+	uint32_t shift = (val >> 24) & 7;
1014
+	if (shift == 7)
1232 1015
 		card.transfer_count = 1;
1233
-	else if(shift == 0)
1016
+	else if (!shift)
1234 1017
 		card.transfer_count = 0;
1235 1018
 	else
1236
-		card.transfer_count = (0x100<<shift)/4;
1019
+		card.transfer_count = (0x100 << shift) / 4;
1237 1020
 
1238 1021
 	switch (card.mode)
1239 1022
 	{
1240
-	case CardMode_Normal:
1241
-		break;
1023
+		case CardMode_Normal:
1024
+			break;
1242 1025
 
1243
-	case CardMode_KEY1:
1244
-		{
1026
+		case CardMode_KEY1:
1245 1027
 			// TODO
1246 1028
 			//INFO("Cartridge: KEY1 mode unsupported.\n");
1247 1029
 
... ...
@@ -1251,826 +1033,501 @@ void FASTCALL MMU_writeToGCControl(uint32_t val)
1251 1033
 			val &= 0x7F7FFFFF;
1252 1034
 			T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1253 1035
 			return;
1254
-		}
1255
-		break;
1256
-	case CardMode_KEY2:
1036
+		case CardMode_KEY2:
1257 1037
 			//INFO("Cartridge: KEY2 mode unsupported.\n");
1258
-		break;
1038
+			break;
1259 1039
 	}
1260 1040
 
1261
-	switch(card.command[0])
1041
+	switch (card.command[0])
1262 1042
 	{
1263
-	case 0x9F: //Dummy
1264
-		card.address = 0;
1265
-		card.transfer_count = 0x800;
1266
-		break;
1267
-
1268
-	//case 0x90: //Get ROM chip ID
1269
-	//	break;
1043
+		case 0x9F: // Dummy
1044
+			card.address = 0;
1045
+			card.transfer_count = 0x800;
1046
+			break;
1270 1047
 
1271
-	case 0x3C: //Switch to KEY1 mode
1272
-		card.mode = CardMode_KEY1;
1273
-		break;
1048
+		case 0x3C: // Switch to KEY1 mode
1049
+			card.mode = CardMode_KEY1;
1050
+			break;
1274 1051
 
1275
-	default:
1276
-		//fall through to the special slot1 handler
1277
-		slot1_device.write32(TEST_PROCNUM, REG_GCROMCTRL,val);
1278
-		break;
1052
+		default:
1053
+			// fall through to the special slot1 handler
1054
+			slot1_device.write32(TEST_PROCNUM, REG_GCROMCTRL, val);
1279 1055
 	}
1280 1056
 
1281
-	if(card.transfer_count == 0)
1057
+	if (!card.transfer_count)
1282 1058
 	{
1283 1059
 		val &= 0x7F7FFFFF;
1284 1060
 		T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1285 1061
 		return;
1286 1062
 	}
1287 1063
 
1288
-    val |= 0x00800000;
1289
-    T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1064
+	val |= 0x00800000;
1065
+	T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1290 1066
 
1291 1067
 	// Launch DMA if start flag was set to "DS Cart"
1292 1068
 	//printf("triggering card dma\n");
1293 1069
 	triggerDma(EDMAMode_Card);
1294 1070
 }
1295 1071
 
1296
-
1297
-
1298
-template<int PROCNUM>
1299
-uint32_t MMU_readFromGC()
1072
+template<int PROCNUM> uint32_t MMU_readFromGC()
1300 1073
 {
1301
-	const int TEST_PROCNUM = PROCNUM;
1074
+	int TEST_PROCNUM = PROCNUM;
1302 1075
 
1303 1076
 	nds_dscard& card = MMU.dscard[TEST_PROCNUM];
1304 1077
 	uint32_t val = 0;
1305 1078
 
1306
-	if(card.transfer_count == 0)
1079
+	if (!card.transfer_count)
1307 1080
 		return 0;
1308 1081
 
1309
-	switch(card.command[0])
1082
+	switch (card.command[0])
1310 1083
 	{
1311
-		case 0x9F: //Dummy
1084
+		case 0x9F: // Dummy
1312 1085
 			val = 0xFFFFFFFF;
1313 1086
 			break;
1314 1087
 
1315
-		case 0x3C: //Switch to KEY1 mode
1088
+		case 0x3C: // Switch to KEY1 mode
1316 1089
 			val = 0xFFFFFFFF;
1317 1090
 			break;
1318 1091
 
1319 1092
 		default:
1320 1093
 			val = slot1_device.read32(TEST_PROCNUM, REG_GCDATAIN);
1321
-			break;
1322 1094
 	}
1323 1095
 
1324
-	card.address += 4;	// increment address
1096
+	card.address += 4; // increment address
1325 1097
 
1326
-	card.transfer_count--;	// update transfer counter
1327
-	if(card.transfer_count) // if transfer is not ended
1328
-		return val;	// return data
1098
+	--card.transfer_count; // update transfer counter
1099
+	if (card.transfer_count) // if transfer is not ended
1100
+		return val; // return data
1329 1101
 
1330 1102
 	// transfer is done
1331
-	T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4,
1332
-		T1ReadLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4) & 0x7F7FFFFF);
1103
+	T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, T1ReadLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4) & 0x7F7FFFFF);
1333 1104
 
1334 1105
 	// if needed, throw irq for the end of transfer
1335
-	if(MMU.AUX_SPI_CNT & 0x4000)
1106
+	if (MMU.AUX_SPI_CNT & 0x4000)
1336 1107
 		NDS_makeIrq(TEST_PROCNUM, IRQ_BIT_GC_TRANSFER_COMPLETE);
1337 1108
 
1338 1109
 	return val;
1339 1110
 }
1340 1111
 
1341
-
1342
-
1343
-//does some validation on the game's choice of IF value, correcting it if necessary
1344
-/*static void validateIF_arm9()
1345
-{
1346
-}*/
1347
-
1348 1112
 template<int PROCNUM> static void REG_IF_WriteByte(uint32_t addr, uint8_t val)
1349 1113
 {
1350
-	//the following bits are generated from logic and should not be affected here
1351
-	//Bit 21    NDS9 only: Geometry Command FIFO
1352
-	//arm9: IF &= ~0x00200000;
1353
-	//arm7: IF &= ~0x00000000;
1354
-	//UPDATE IN setIF() ALSO!!!!!!!!!!!!!!!!
1355
-	//UPDATE IN mmu_loadstate ALSO!!!!!!!!!!!!
1356
-	if(addr==2)
1114
+	// the following bits are generated from logic and should not be affected here
1115
+	// Bit 21    NDS9 only: Geometry Command FIFO
1116
+	// arm9: IF &= ~0x00200000;
1117
+	// arm7: IF &= ~0x00000000;
1118
+	// UPDATE IN setIF() ALSO!!!!!!!!!!!!!!!!
1119
+	// UPDATE IN mmu_loadstate ALSO!!!!!!!!!!!!
1120
+	if (addr == 2)
1357 1121
 	{
1358
-		if(PROCNUM==ARMCPU_ARM9)
1122
+		if (PROCNUM == ARMCPU_ARM9)
1359 1123
 			val &= ~0x20;
1360 1124
 		else
1361 1125
 			val &= ~0x00;
1362 1126
 	}
1363 1127
 
1364
-	//ZERO 01-dec-2010 : I am no longer sure this approach is correct.. it proved to be wrong for IPC fifo.......
1365
-	//it seems as if IF bits should always be cached (only the user can clear them)
1128
+	// ZERO 01-dec-2010 : I am no longer sure this approach is correct.. it proved to be wrong for IPC fifo.......
1129
+	// it seems as if IF bits should always be cached (only the user can clear them)
1366 1130
 
1367
-	MMU.reg_IF_bits[PROCNUM] &= (~(((uint32_t)val)<<(addr<<3)));
1131
+	MMU.reg_IF_bits[PROCNUM] &= ~(static_cast<uint32_t>(val) << (addr << 3));
1368 1132
 	NDS_Reschedule();
1369 1133
 }
1370 1134
 
1371
-template<int PROCNUM> static void REG_IF_WriteWord(uint32_t addr,uint16_t val)
1135
+template<int PROCNUM> static void REG_IF_WriteWord(uint32_t addr, uint16_t val)
1372 1136
 {
1373
-	REG_IF_WriteByte<PROCNUM>(addr,val&0xFF);
1374
-	REG_IF_WriteByte<PROCNUM>(addr+1,(val>>8)&0xFF);
1137
+	REG_IF_WriteByte<PROCNUM>(addr, val & 0xFF);
1138
+	REG_IF_WriteByte<PROCNUM>(addr + 1, (val >> 8) & 0xFF);
1375 1139
 }
1376 1140
 
1377 1141
 template<int PROCNUM> static void REG_IF_WriteLong(uint32_t val)
1378 1142
 {
1379
-	REG_IF_WriteByte<PROCNUM>(0,val&0xFF);
1380
-	REG_IF_WriteByte<PROCNUM>(1,(val>>8)&0xFF);
1381
-	REG_IF_WriteByte<PROCNUM>(2,(val>>16)&0xFF);
1382
-	REG_IF_WriteByte<PROCNUM>(3,(val>>24)&0xFF);
1143
+	REG_IF_WriteByte<PROCNUM>(0, val & 0xFF);
1144
+	REG_IF_WriteByte<PROCNUM>(1, (val >> 8) & 0xFF);
1145
+	REG_IF_WriteByte<PROCNUM>(2, (val >> 16) & 0xFF);
1146
+	REG_IF_WriteByte<PROCNUM>(3, (val >> 24) & 0xFF);
1383 1147
 }
1384 1148
 
1385
-template<int PROCNUM>
1386
-uint32_t MMU_struct::gen_IF()
1149
+template<int PROCNUM> uint32_t MMU_struct::gen_IF()
1387 1150
 {
1388
-	uint32_t IF = reg_IF_bits[PROCNUM];
1389
-
1390
-	/*if(PROCNUM==ARMCPU_ARM9)
1391
-	{
1392
-		//according to gbatek, these flags are forced on until the condition is removed.
1393
-		//no proof of this though...
1394
-		switch(MMU_new.gxstat.gxfifo_irq)
1395
-		{
1396
-		case 0: //never
1397
-			break;
1398
-		case 1: //less than half full
1399
-			if(MMU_new.gxstat.fifo_low)
1400
-				IF |= IRQ_MASK_ARM9_GXFIFO;
1401
-			break;
1402
-		case 2: //empty
1403
-			if(MMU_new.gxstat.fifo_empty)
1404
-				IF |= IRQ_MASK_ARM9_GXFIFO;
1405
-			break;
1406
-		case 3: //reserved/unknown
1407
-			break;
1408
-		}
1409
-	}*/
1410
-
1411
-	return IF;
1151
+	return this->reg_IF_bits[PROCNUM];
1412 1152
 }
1413 1153
 
1414
-/*static void writereg_DISP3DCNT(const int size, const uint32_t adr, const uint32_t val)
1154
+static inline void MMU_IPCSync(uint8_t proc, uint32_t val)
1415 1155
 {
1416
-	//UGH. rewrite this shite to use individual values and reconstruct the return value instead of packing things in this !@#)ing register
1156
+	uint32_t sync_l = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x180) & 0xFFFF;
1157
+	uint32_t sync_r = T1ReadLong(MMU.MMU_MEM[proc ^ 1][0x40], 0x180) & 0xFFFF;
1417 1158
 
1418
-	//nanostray2 cutscene will test this vs old desmumes by using some kind of 32bit access for setting up this reg for cutscenes
1419
-	switch(size)
1420
-	{
1421
-	case 8:
1422
-		switch(adr)
1423
-		{
1424
-		case REG_DISPA_DISP3DCNT:
1425
-			MMU.reg_DISP3DCNT_bits &= 0xFFFFFF00;
1426
-			MMU.reg_DISP3DCNT_bits |= val;
1427
-			//gfx3d_Control(MMU.reg_DISP3DCNT_bits);
1428
-			break;
1429
-		case REG_DISPA_DISP3DCNT+1:
1430
-			{
1431
-				uint32_t myval = (val & ~0x30) | (~val & ((MMU.reg_DISP3DCNT_bits>>8) & 0x30)); // bits 12,13 are ack bits
1432
-				myval &= 0x7F; //top bit isnt connected
1433
-				MMU.reg_DISP3DCNT_bits = MMU.reg_DISP3DCNT_bits&0xFFFF00FF;
1434
-				MMU.reg_DISP3DCNT_bits |= (myval<<8);
1435
-				//gfx3d_Control(MMU.reg_DISP3DCNT_bits);
1436
-			}
1437
-			break;
1438
-		}
1439
-		break;
1440
-	case 16:
1441
-	case 32:
1442
-		writereg_DISP3DCNT(8,adr,val&0xFF);
1443
-		writereg_DISP3DCNT(8,adr+1,(val>>8)&0xFF);
1444
-		break;
1445
-	}
1446
-}*/
1447
-
1448
-/*static uint32_t readreg_DISP3DCNT(const int size, const uint32_t adr)
1449
-{
1450
-	//UGH. rewrite this shite to use individual values and reconstruct the return value instead of packing things in this !@#)ing register
1451
-	switch(size)
1452
-	{
1453
-	case 8:
1454
-		switch(adr)
1455
-		{
1456
-		case REG_DISPA_DISP3DCNT:
1457
-			return MMU.reg_DISP3DCNT_bits & 0xFF;
1458
-		case REG_DISPA_DISP3DCNT+1:
1459
-			return ((MMU.reg_DISP3DCNT_bits)>>8)& 0xFF;
1460
-		}
1461
-		break;
1462
-	case 16:
1463
-	case 32:
1464
-		return readreg_DISP3DCNT(8,adr)|(readreg_DISP3DCNT(8,adr+1)<<8);
1465
-	}
1466
-	assert(false);
1467
-	return 0;
1468
-}*/
1469
-
1470
-
1471
-/*static uint32_t readreg_POWCNT1(const int size, const uint32_t adr) {
1472
-	switch(size)
1473
-	{
1474
-	case 8:
1475
-		switch(adr)
1476
-		{
1477
-		case REG_POWCNT1: {
1478
-			uint8_t ret = 0;
1479
-			ret |= nds.power1.lcd?BIT(0):0;
1480
-			ret |= nds.power1.gpuMain?BIT(1):0;
1481
-			ret |= nds.power1.gfx3d_render?BIT(2):0;
1482
-			ret |= nds.power1.gfx3d_geometry?BIT(3):0;
1483
-			return ret;
1484
-			}
1485
-		case REG_POWCNT1+1: {
1486
-			uint8_t ret = 0;
1487
-			ret |= nds.power1.gpuSub?BIT(1):0;
1488
-			ret |= nds.power1.dispswap?BIT(7):0;
1489
-			return ret;
1490
-			}
1491
-		}
1492
-	case 16:
1493
-	case 32:
1494
-		return readreg_POWCNT1(8,adr)|(readreg_POWCNT1(8,adr+1)<<8);
1495
-	}
1496
-	assert(false);
1497
-	return 0;
1498
-}*/
1499
-/*static void writereg_POWCNT1(const int size, const uint32_t adr, const uint32_t val) {
1500
-	switch(size)
1501
-	{
1502
-	case 8:
1503
-		switch(adr)
1504
-		{
1505
-		case REG_POWCNT1:
1506
-			nds.power1.lcd = BIT0(val);
1507
-			nds.power1.gpuMain = BIT1(val);
1508
-			nds.power1.gfx3d_render = BIT2(val);
1509
-			nds.power1.gfx3d_geometry = BIT3(val);
1510
-			break;
1511
-		case REG_POWCNT1+1:
1512
-			nds.power1.gpuSub = BIT1(val);
1513
-			nds.power1.dispswap = BIT7(val);
1514
-			if(nds.power1.dispswap)
1515
-			{
1516
-				//printf("Main core on top (vcount=%d)\n",nds.VCount);
1517
-				//MainScreen.offset = 0;
1518
-				//SubScreen.offset = 192;
1519
-			}
1520
-			else
1521
-			{
1522
-				//printf("Main core on bottom (vcount=%d)\n",nds.VCount);
1523
-				//MainScreen.offset = 192;
1524
-				//SubScreen.offset = 0;
1525
-			}
1526
-			break;
1527
-		}
1528
-		break;
1529
-	case 16:
1530
-	case 32:
1531
-		writereg_POWCNT1(8,adr,val&0xFF);
1532
-		writereg_POWCNT1(8,adr+1,(val>>8)&0xFF);
1533
-		break;
1534
-	}
1535
-}*/
1536
-
1537
-static inline void MMU_IPCSync(uint8_t proc, uint32_t val)
1538
-{
1539
-	//INFO("IPC%s sync 0x%04X (0x%02X|%02X)\n", proc?"7":"9", val, val >> 8, val & 0xFF);
1540
-	uint32_t sync_l = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x180) & 0xFFFF;
1541
-	uint32_t sync_r = T1ReadLong(MMU.MMU_MEM[proc^1][0x40], 0x180) & 0xFFFF;
1542
-
1543
-	sync_l = ( sync_l & 0x000F ) | ( val & 0x0F00 );
1544
-	sync_r = ( sync_r & 0x6F00 ) | ( (val >> 8) & 0x000F );
1159
+	sync_l = (sync_l & 0x000F) | (val & 0x0F00);
1160
+	sync_r = (sync_r & 0x6F00) | ((val >> 8) & 0x000F);
1545 1161
 
1546 1162
 	sync_l |= val & 0x6000;
1547 1163
 
1548
-	/*if(nds.ensataEmulation && proc==1 && nds.ensataIpcSyncCounter<9) {
1549
-		uint32_t iteration = (val&0x0F00)>>8;*/
1550
-
1551
-		/*if(iteration==8-nds.ensataIpcSyncCounter)
1552
-			nds.ensataIpcSyncCounter++;
1553
-		else printf("ERROR: ENSATA IPC SYNC HACK FAILED; BAD THINGS MAY HAPPEN\n");*/
1554
-
1555
-		//for some reason, the arm9 doesn't handshake when ensata is detected.
1556
-		//so we complete the protocol here, which is to mirror the values 8..0 back to
1557
-		//the arm7 as they are written by the arm7
1558
-		/*sync_r &= 0xF0FF;
1559
-		sync_r |= (iteration<<8);
1560
-		sync_l &= 0xFFF0;
1561
-		sync_l |= iteration;
1562
-	}*/
1563
-
1564 1164
 	T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, sync_l);
1565
-	T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, sync_r);
1165
+	T1WriteLong(MMU.MMU_MEM[proc ^ 1][0x40], 0x180, sync_r);
1566 1166
 
1567 1167
 	if ((sync_l & IPCSYNC_IRQ_SEND) && (sync_r & IPCSYNC_IRQ_RECV))
1568
-		NDS_makeIrq(proc^1, IRQ_BIT_IPCSYNC);
1168
+		NDS_makeIrq(proc ^ 1, IRQ_BIT_IPCSYNC);
1569 1169
 
1570 1170
 	NDS_Reschedule();
1571 1171
 }
1572 1172
 
1573 1173
 static inline uint16_t read_timer(int proc, int timerIndex)
1574 1174
 {
1575
-	//chained timers are always up to date
1576
-	if(MMU.timerMODE[proc][timerIndex] == 0xFFFF)
1175
+	// chained timers are always up to date
1176
+	if (MMU.timerMODE[proc][timerIndex] == 0xFFFF)
1577 1177
 		return MMU.timer[proc][timerIndex];
1578 1178
 
1579
-	//sometimes a timer will be read when it is not enabled.
1580
-	//we should have the value cached
1581
-	if(!MMU.timerON[proc][timerIndex])
1179
+	// sometimes a timer will be read when it is not enabled.
1180
+	// we should have the value cached
1181
+	if (!MMU.timerON[proc][timerIndex])
1582 1182
 		return MMU.timer[proc][timerIndex];
1583 1183
 
1584
-	//for unchained timers, we do not keep the timer up to date. its value will need to be calculated here
1585
-	int32_t diff = (int32_t)(nds.timerCycle[proc][timerIndex] - nds_timer);
1586
-	assert(diff>=0);
1587
-	if(diff<0)
1588
-		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: TIME READ DIFF < 0 (%d) (%d) (%d)\n",diff,timerIndex,MMU.timerMODE[proc][timerIndex]);
1184
+	// for unchained timers, we do not keep the timer up to date. its value will need to be calculated here
1185
+	int32_t diff = static_cast<int32_t>(nds.timerCycle[proc][timerIndex] - nds_timer);
1186
+	assert(diff >= 0);
1187
+	if (diff < 0)
1188
+		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: TIME READ DIFF < 0 (%d) (%d) (%d)\n", diff, timerIndex, MMU.timerMODE[proc][timerIndex]);
1589 1189
 
1590
-	int32_t units = diff / (1<<MMU.timerMODE[proc][timerIndex]);
1190
+	int32_t units = diff / (1 << MMU.timerMODE[proc][timerIndex]);
1591 1191
 	int32_t ret;
1592 1192
 
1593
-	if(units==65536)
1594
-		ret = 0; //I'm not sure why this is happening...
1595
-		//whichever instruction setup this counter should advance nds_timer (I think?) and the division should truncate down to 65535 immediately
1596
-	else if(units>65536) {
1597
-		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: UNITS %d:%d = %d\n",proc,timerIndex,units);
1193
+	if (units == 65536)
1194
+		ret = 0; // I'm not sure why this is happening...
1195
+	// whichever instruction setup this counter should advance nds_timer (I think?) and the division should truncate down to 65535 immediately
1196
+	else if (units > 65536)
1197
+	{
1198
+		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: UNITS %d:%d = %d\n", proc, timerIndex, units);
1598 1199
 		ret = 0;
1599 1200
 	}
1600
-	else ret = 65535 - units;
1201
+	else
1202
+		ret = 65535 - units;
1601 1203
 
1602 1204
 	return static_cast<uint16_t>(ret);
1603 1205
 }
1604 1206
 
1605 1207
 static inline void write_timer(int proc, int timerIndex, uint16_t val)
1606 1208
 {
1607
-#if 0
1608
-	int mask		= ((val&0x80)>>7) << timerIndex;
1609
-	MMU.CheckTimers = (MMU.CheckTimers & (~mask)) | mask;
1610
-#endif
1611
-
1612
-	if(val&0x80)
1209
+	if (val & 0x80)
1613 1210
 		MMU.timer[proc][timerIndex] = MMU.timerReload[proc][timerIndex];
1614
-	else
1615
-	{
1616
-		if(MMU.timerON[proc][timerIndex])
1617
-			//read the timer value one last time
1618
-			MMU.timer[proc][timerIndex] = read_timer(proc,timerIndex);
1619
-	}
1211
+	else if (MMU.timerON[proc][timerIndex])
1212
+		// read the timer value one last time
1213
+		MMU.timer[proc][timerIndex] = read_timer(proc, timerIndex);
1620 1214
 
1621 1215
 	MMU.timerON[proc][timerIndex] = val & 0x80;
1622 1216
 
1623
-	switch(val&7)
1217
+	switch (val & 7)
1624 1218
 	{
1625
-		case 0 :
1626
-			MMU.timerMODE[proc][timerIndex] = 0+1;
1219
+		case 0:
1220
+			MMU.timerMODE[proc][timerIndex] = 1;
1627 1221
 			break;
1628
-		case 1 :
1629
-			MMU.timerMODE[proc][timerIndex] = 6+1;
1222
+		case 1:
1223
+			MMU.timerMODE[proc][timerIndex] = 7;
1630 1224
 			break;
1631
-		case 2 :
1632
-			MMU.timerMODE[proc][timerIndex] = 8+1;
1225
+		case 2:
1226
+			MMU.timerMODE[proc][timerIndex] = 9;
1633 1227
 			break;
1634
-		case 3 :
1635
-			MMU.timerMODE[proc][timerIndex] = 10+1;
1228
+		case 3:
1229
+			MMU.timerMODE[proc][timerIndex] = 11;
1636 1230
 			break;
1637
-		default :
1231
+		default:
1638 1232
 			MMU.timerMODE[proc][timerIndex] = 0xFFFF;
1639
-			break;
1640 1233
 	}
1641 1234
 
1642 1235
 	int remain = 65536 - MMU.timerReload[proc][timerIndex];
1643
-	nds.timerCycle[proc][timerIndex] = nds_timer + (remain<<MMU.timerMODE[proc][timerIndex]);
1236
+	nds.timerCycle[proc][timerIndex] = nds_timer + (remain << MMU.timerMODE[proc][timerIndex]);
1644 1237
 
1645
-	T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x102+timerIndex*4, val);
1238
+	T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x102 + timerIndex * 4, val);
1646 1239
 	NDS_RescheduleTimers();
1647 1240
 }
1648 1241
 
1649
-//extern CACHE_ALIGN MatrixStack	mtxStack[4];
1650 1242
 uint32_t TGXSTAT::read32()
1651 1243
 {
1652 1244
 	uint32_t ret = 0;
1653 1245
 
1654
-	ret |= tb|(tr<<1);
1246
+	ret |= this->tb | (this->tr << 1);
1655 1247
 
1656
-	//int _hack_getMatrixStackLevel(int which);
1248
+	ret |= this->sb << 14; // stack busy
1249
+	ret |= this->se << 15;
1250
+	ret |= 255 << 16;
1657 1251
 
1658
-	// stack position always equal zero. possible timings is wrong
1659
-	// using in "The Wild West"
1660
-	//ret |= ((_hack_getMatrixStackLevel(0) << 13) | (_hack_getMatrixStackLevel(1) << 8)); //matrix stack levels //no proof that these are needed yet
1661
-
1662
-	ret |= sb<<14;	//stack busy
1663
-	ret |= se<<15;
1664
-	ret |= 255<<16;//(std::min(gxFIFO.size,(uint32_t)255))<<16;
1665
-	//if(gxFIFO.size>=255) ret |= BIT(24); //fifo full
1666
-	//if(gxFIFO.size<128) ret |= BIT(25); //fifo half
1667
-	//if(gxFIFO.size==0) ret |= BIT(26); //fifo empty
1668
-	//determine busy flag.
1669
-	//if we're waiting for a flush, we're busy
1670
-	//if(isSwapBuffers) ret |= BIT(27);
1671
-	//if fifo is nonempty, we're busy
1672
-	//if(gxFIFO.size!=0) ret |= BIT(27);
1673
-
1674
-	ret |= ((gxfifo_irq & 0x3) << 30); //user's irq flags
1252
+	ret |= (this->gxfifo_irq & 0x3) << 30; // user's irq flags
1675 1253
 
1676 1254
 	//printf("vc=%03d Returning gxstat read: %08X\n",nds.VCount,ret);
1677 1255
 
1678
-	//ret = (2 << 8);
1679
-	//INFO("gxSTAT 0x%08X (proj %i, pos %i)\n", ret, _hack_getMatrixStackLevel(1), _hack_getMatrixStackLevel(2));
1680 1256
 	return ret;
1681 1257
 }
1682 1258
 
1683
-void TGXSTAT::write32(const uint32_t val)
1259
+void TGXSTAT::write32(uint32_t val)
1684 1260
 {
1685
-	gxfifo_irq = (val>>30)&3;
1686
-	if(BIT15(val))
1261
+	this->gxfifo_irq = (val >> 30) & 3;
1262
+	if (BIT15(val))
1687 1263
 	{
1688 1264
 		// Writing "1" to Bit15 does reset the Error Flag (Bit15),
1689 1265
 		// and additionally resets the Projection Stack Pointer (Bit13)
1690 1266
 		//mtxStack[0].position = 0;
1691
-		se = 0; //clear stack error flag
1267
+		this->se = 0; // clear stack error flag
1692 1268
 	}
1693 1269
 	//printf("gxstat write: %08X while gxfifo.size=%d\n",val,gxFIFO.size);
1694
-
1695
-		//if (val & (1<<29))		// clear? (only in homebrew?)
1696
-	//{
1697
-	//	GFX_PIPEclear();
1698
-	//	GFX_FIFOclear();
1699
-	//	return;
1700
-	//}
1701
-}
1702
-
1703
-/*void TGXSTAT::savestate(EMUFILE *f)
1704
-{
1705
-	write32le(1,f); //version
1706
-	write8le(tb,f); write8le(tr,f); write8le(se,f); write8le(gxfifo_irq,f); write8le(sb,f);
1707
-}*/
1708
-bool TGXSTAT::loadstate(EMUFILE *f)
1709
-{
1710
-	uint32_t version;
1711
-	if(read32le(&version,f) != 1) return false;
1712
-	if(version > 1) return false;
1713
-
1714
-	read8le(&tb,f); read8le(&tr,f); read8le(&se,f); read8le(&gxfifo_irq,f);
1715
-	if (version >= 1)
1716
-		read8le(&sb,f);
1717
-
1718
-	return true;
1719 1270
 }
1720 1271
 
1721
-//this could be inlined...
1722
-void MMU_struct_new::write_dma(const int proc, const int size, const uint32_t _adr, const uint32_t val)
1272
+// this could be inlined...
1273
+void MMU_struct_new::write_dma(int proc, int size, uint32_t _adr, uint32_t val)
1723 1274
 {
1724 1275
 	//printf("%08lld -- write_dma: %d %d %08X %08X\n",nds_timer,proc,size,_adr,val);
1725
-	const uint32_t adr = _adr - _REG_DMA_CONTROL_MIN;
1726
-	const uint32_t chan = adr/12;
1727
-	const uint32_t regnum = (adr - chan*12)>>2;
1276
+	uint32_t adr = _adr - _REG_DMA_CONTROL_MIN;
1277
+	uint32_t chan = adr / 12;
1278
+	uint32_t regnum = (adr - chan * 12) >> 2;
1728 1279
 
1729
-	if(proc==0&&chan==0)
1730
-	{
1731
-		//int zzz=9;
1732
-	}
1733
-
1734
-	if(proc==1) {
1735
-		//int zzz=9;
1736
-	}
1737
-
1738
-	MMU_new.dma[proc][chan].regs[regnum]->write(size,adr,val);
1280
+	MMU_new.dma[proc][chan].regs[regnum]->write(size, adr, val);
1739 1281
 }
1740 1282
 
1741
-
1742
-//this could be inlined...
1743
-uint32_t MMU_struct_new::read_dma(const int proc, const int size, const uint32_t _adr)
1283
+// this could be inlined...
1284
+uint32_t MMU_struct_new::read_dma(int proc, int size, uint32_t _adr)
1744 1285
 {
1745
-	const uint32_t adr = _adr - _REG_DMA_CONTROL_MIN;
1746
-	const uint32_t chan = adr/12;
1747
-	const uint32_t regnum = (adr - chan*12)>>2;
1286
+	uint32_t adr = _adr - _REG_DMA_CONTROL_MIN;
1287
+	uint32_t chan = adr / 12;
1288
+	uint32_t regnum = (adr - chan * 12) >> 2;
1748 1289
 
1749
-	const uint32_t temp = MMU_new.dma[proc][chan].regs[regnum]->read(size,adr);
1290
+	uint32_t temp = MMU_new.dma[proc][chan].regs[regnum]->read(size, adr);
1750 1291
 	//printf("%08lld --  read_dma: %d %d %08X = %08X\n",nds_timer,proc,size,_adr,temp);
1751 1292
 
1752
-
1753
-
1754
-	if(temp == 0xAF00 && size == 16)
1755
-	{
1756
-		//int zzz=9;
1757
-	}
1758
-
1759 1293
 	return temp;
1760 1294
 }
1761 1295
 
1762 1296
 MMU_struct_new::MMU_struct_new()
1763 1297
 {
1764
-	for(int i=0;i<2;i++)
1765
-		for(int j=0;j<4;j++) {
1298
+	for (int i = 0; i < 2; ++i)
1299
+		for (int j = 0; j < 4; ++j)
1300
+		{
1766 1301
 			dma[i][j].procnum = i;
1767 1302
 			dma[i][j].chan = j;
1768 1303
 		}
1769 1304
 }
1770 1305
 
1771
-bool DmaController::loadstate(EMUFILE* f)
1772
-{
1773
-	uint32_t version;
1774
-	if(read32le(&version,f) != 1) return false;
1775
-	if(version >1) return false;
1776
-
1777
-	read8le(&enable,f); read8le(&irq,f); read8le(&repeatMode,f); read8le(&_startmode,f);
1778
-	read8le(&userEnable,f);
1779
-	read32le(&wordcount,f);
1780
-	uint8_t temp;
1781
-	read8le(&temp,f); startmode = (EDMAMode)temp;
1782
-	read8le(&temp,f); bitWidth = (EDMABitWidth)temp;
1783
-	read8le(&temp,f); sar = (EDMASourceUpdate)temp;
1784
-	read8le(&temp,f); dar = (EDMADestinationUpdate)temp;
1785
-	read32le(&saddr,f); read32le(&daddr,f);
1786
-	read32le(reinterpret_cast<uint32_t *>(&dmaCheck),f); read32le(reinterpret_cast<uint32_t *>(&running),f); read32le(reinterpret_cast<uint32_t *>(&paused),f); read32le(reinterpret_cast<uint32_t *>(&triggered),f);
1787
-	read64le(&nextEvent,f);
1788
-
1789
-	if(version==1)
1790
-	{
1791
-		read32le(&saddr_user,f);
1792
-		read32le(&daddr_user,f);
1793
-	}
1794
-
1795
-	return true;
1796
-}
1797
-
1798
-/*void DmaController::savestate(EMUFILE *f)
1306
+void DmaController::write32(uint32_t val)
1799 1307
 {
1800
-	write32le(1,f); //version
1801
-	write8le(enable,f); write8le(irq,f); write8le(repeatMode,f); write8le(_startmode,f);
1802
-	write8le(userEnable,f);
1803
-	write32le(wordcount,f);
1804
-	write8le(startmode,f);
1805
-	write8le(bitWidth,f);
1806
-	write8le(sar,f);
1807
-	write8le(dar,f);
1808
-	write32le(saddr,f); write32le(daddr,f);
1809
-	write32le(check,f); write32le(running,f); write32le(paused,f); write32le(triggered,f);
1810
-	write64le(nextEvent,f);
1811
-	write32le(saddr_user,f);
1812
-	write32le(daddr_user,f);
1813
-}*/
1814
-
1815
-void DmaController::write32(const uint32_t val)
1816
-{
1817
-	if(this->chan==0 && this->procnum==0)
1818
-	{
1819
-		//int zzz=9;
1820
-	}
1821
-	if(running)
1822
-	{
1823
-		//desp triggers this a lot. figure out whats going on
1824
-		//printf("thats weird..user edited dma control while it was running\n");
1825
-	}
1826 1308
 	//printf("dma %d,%d WRITE %08X\n",procnum,chan,val);
1827
-	wordcount = val&0x1FFFFF;
1828
-	if(wordcount==0x9FbFC || wordcount == 0x1FFFFC || wordcount == 0x1EFFFC || wordcount == 0x1FFFFF) {
1829
-		//int zzz=9;
1830
-	}
1831
-	//uint8_t wasRepeatMode = repeatMode;
1832
-	uint8_t wasEnable = enable;
1833
-	uint32_t valhi = val>>16;
1834
-	dar = (EDMADestinationUpdate)((valhi>>5)&3);
1835
-	sar = (EDMASourceUpdate)((valhi>>7)&3);
1836
-	repeatMode = static_cast<uint8_t>(BIT9(valhi));
1837
-	bitWidth = (EDMABitWidth)BIT10(valhi);
1838
-	_startmode = (valhi>>11)&7;
1839
-	if(procnum==ARMCPU_ARM7) _startmode &= 6;
1840
-	irq = static_cast<uint8_t>(BIT14(valhi));
1841
-	enable = static_cast<uint8_t>(BIT15(valhi));
1842
-
1843
-	if(val==0x84400076 && saddr ==0x023BCEC4)
1844
-	{
1845
-		//int zzz=9;
1846
-	}
1847
-
1848
-	//if(irq) printf("!!!!!!!!!!!!IRQ!!!!!!!!!!!!!\n");
1849
-
1850
-	//make sure we don't get any old triggers
1851
-	if(!wasEnable && enable)
1852
-		triggered = false;
1853
-
1854
-	if(enable)
1855
-	{
1856
-		//address registers are reloaded from user's settings whenever dma is enabled
1857
-		//this is tested well by contra4 classic games, which use this to hdma scroll registers
1858
-		//specifically in the fit-screen mode.
1859
-		saddr = saddr_user;
1860
-		daddr = daddr_user;
1309
+	this->wordcount = val & 0x1FFFFF;
1310
+	uint8_t wasEnable = this->enable;
1311
+	uint32_t valhi = val >> 16;
1312
+	this->dar = static_cast<EDMADestinationUpdate>((valhi >> 5) & 3);
1313
+	this->sar = static_cast<EDMASourceUpdate>((valhi >> 7) & 3);
1314
+	this->repeatMode = static_cast<uint8_t>(BIT9(valhi));
1315
+	this->bitWidth = static_cast<EDMABitWidth>(BIT10(valhi));
1316
+	this->_startmode = (valhi >> 11) & 7;
1317
+	if (this->procnum == ARMCPU_ARM7)
1318
+		this->_startmode &= 6;
1319
+	this->irq = static_cast<uint8_t>(BIT14(valhi));
1320
+	this->enable = static_cast<uint8_t>(BIT15(valhi));
1321
+
1322
+	// make sure we don't get any old triggers
1323
+	if (!wasEnable && this->enable)
1324
+		this->triggered = false;
1325
+
1326
+	if (this->enable)
1327
+	{
1328
+		// address registers are reloaded from user's settings whenever dma is enabled
1329
+		// this is tested well by contra4 classic games, which use this to hdma scroll registers
1330
+		// specifically in the fit-screen mode.
1331
+		this->saddr = this->saddr_user;
1332
+		this->daddr = this->daddr_user;
1861 1333
 	}
1862 1334
 
1863 1335
 	//printf("dma %d,%d set to startmode %d with wordcount set to: %08X\n",procnum,chan,_startmode,wordcount);
1864
-if(_startmode==0 && wordcount==1) {
1865
-	//int zzz=9;
1866
-}
1867
-	if(enable)
1868
-	{
1869
-		//int zzz=9;
1870
-	}
1871
-
1872
-	//analyze enabling and startmode.
1873
-	//note that we only do this if the dma was freshly enabled.
1874
-	//we should probably also only be latching these other regs in that case too..
1875
-	//but for now just this one will do (otherwise the dma repeat stop procedure (in this case the ff4 title menu load with gamecard dma) will fail)
1336
+	// analyze enabling and startmode.
1337
+	// note that we only do this if the dma was freshly enabled.
1338
+	// we should probably also only be latching these other regs in that case too..
1339
+	// but for now just this one will do (otherwise the dma repeat stop procedure (in this case the ff4 title menu load with gamecard dma) will fail)
1876 1340
 	//if(!running) enable = userEnable;
1877 1341
 
1878
-	//if we were previously in a triggered mode, and were already enabled,
1879
-	//then don't re-trigger now. this is rather confusing..
1880
-	//we really only want to auto-trigger gxfifo and immediate modes.
1881
-	//but we don't know what mode we're in yet.
1882
-	//so this is our workaround
1883
-	//(otherwise the dma repeat stop procedure (in this case the ff4 title menu load with gamecard dma) will fail)
1342
+	// if we were previously in a triggered mode, and were already enabled,
1343
+	// then don't re-trigger now. this is rather confusing..
1344
+	// we really only want to auto-trigger gxfifo and immediate modes.
1345
+	// but we don't know what mode we're in yet.
1346
+	// so this is our workaround
1347
+	// (otherwise the dma repeat stop procedure (in this case the ff4 title menu load with gamecard dma) will fail)
1884 1348
 	bool doNotStart = false;
1885
-	if(startmode != EDMAMode_Immediate/* && startmode != EDMAMode_GXFifo*/ && wasEnable) doNotStart = true;
1349
+	if (this->startmode != EDMAMode_Immediate && wasEnable)
1350
+		doNotStart = true;
1886 1351
 
1887
-	//this dma may need to trigger now, so give it a chance
1352
+	// this dma may need to trigger now, so give it a chance
1888 1353
 	//if(!(wasRepeatMode && !repeatMode)) //this was an older test
1889
-	if(!doNotStart)
1890
-		doSchedule();
1891
-
1892
-	//driver->DEBUG_UpdateIORegView(BaseDriver::EDEBUG_IOREG_DMA);
1354
+	if (!doNotStart)
1355
+		this->doSchedule();
1893 1356
 }
1894 1357
 
1895 1358
 void DmaController::exec()
1896 1359
 {
1897
-	//this function runs when the DMA ends. the dma start actually queues this event after some kind of guess as to how long the DMA should take
1360
+	// this function runs when the DMA ends. the dma start actually queues this event after some kind of guess as to how long the DMA should take
1898 1361
 
1899
-	//we'll need to unfreeze the arm9 bus now
1900
-	if(procnum==ARMCPU_ARM9) nds.freezeBus &= ~(1<<(chan+1));
1362
+	// we'll need to unfreeze the arm9 bus now
1363
+	if (this->procnum == ARMCPU_ARM9)
1364
+		nds.freezeBus &= ~(1 << (this->chan + 1));
1901 1365
 
1902
-	dmaCheck = false;
1366
+	this->dmaCheck = false;
1903 1367
 
1904
-	if(running)
1368
+	if (this->running)
1905 1369
 	{
1906
-		switch(startmode) {
1907
-			/*case EDMAMode_GXFifo:
1908
-				//this dma mode won't finish always its job when it gets signalled
1909
-				//sometimes it will have words left to transfer.
1910
-				//if(!paused) printf("gxfifo dma ended with %d remaining\n",wordcount); //only print this once
1911
-				if(wordcount>0) {
1912
-					doPause();
1913
-					break;
1914
-				}*/
1915
-			default:
1916
-				doStop();
1917
-				//driver->DEBUG_UpdateIORegView(BaseDriver::EDEBUG_IOREG_DMA);
1918
-				return;
1919
-		}
1370
+		this->doStop();
1371
+		return;
1920 1372
 	}
1921 1373
 
1922
-	if(enable)
1374
+	if (this->enable)
1923 1375
 	{
1924
-		//analyze startmode (this only gets latched when a dma begins)
1925
-		if(procnum==ARMCPU_ARM9) startmode = (EDMAMode)_startmode;
1926
-		else {
1927
-			//arm7 startmode analysis:
1928
-			static const EDMAMode lookup[] = {EDMAMode_Immediate,EDMAMode_VBlank,EDMAMode_Card,EDMAMode7_Wifi};
1929
-			//arm7 has a slightly different startmode encoding
1930
-			startmode = lookup[_startmode>>1];
1931
-			if(startmode == EDMAMode7_Wifi && (chan==1 || chan==3))
1932
-				startmode = EDMAMode7_GBASlot;
1376
+		// analyze startmode (this only gets latched when a dma begins)
1377
+		if (this->procnum == ARMCPU_ARM9)
1378
+			this->startmode = static_cast<EDMAMode>(this->_startmode);
1379
+		else
1380
+		{
1381
+			// arm7 startmode analysis:
1382
+			static const EDMAMode lookup[] = { EDMAMode_Immediate, EDMAMode_VBlank, EDMAMode_Card, EDMAMode7_Wifi };
1383
+			// arm7 has a slightly different startmode encoding
1384
+			this->startmode = lookup[this->_startmode >> 1];
1385
+			if (this->startmode == EDMAMode7_Wifi && (this->chan == 1 || this->chan == 3))
1386
+				this->startmode = EDMAMode7_GBASlot;
1933 1387
 		}
1934 1388
 
1935
-		//make it run, if it is triggered
1936
-		//but first, scan for triggering conditions
1937
-		switch(startmode) {
1389
+		// make it run, if it is triggered
1390
+		// but first, scan for triggering conditions
1391
+		switch (this->startmode)
1392
+		{
1938 1393
 			case EDMAMode_Immediate:
1939
-				triggered = true;
1940
-				break;
1941
-			/*case EDMAMode_GXFifo:
1942
-				if(gxFIFO.size<=127)
1943
-					triggered = true;
1944
-				break;*/
1945
-			default:
1946
-				break;
1394
+				this->triggered = true;
1947 1395
 		}
1948 1396
 
1949
-		if(triggered)
1397
+		if (this->triggered)
1950 1398
 		{
1951
-			//if(procnum==0) printf("vc=%03d %08lld trig type %d dma#%d w/words %d at src:%08X dst:%08X gxf:%d",nds.VCount,nds_timer,startmode,chan,wordcount,saddr,daddr,gxFIFO.size);
1952
-			if(saddr ==0x023BCCEC && wordcount==118) {
1953
-				//int zzz=9;
1954
-			}
1955
-			if(startmode==0 && daddr == 0x4000400) {
1956
-				//int zzz=9;
1957
-			}
1958
-			running = true;
1959
-			paused = false;
1960
-			if(procnum == ARMCPU_ARM9) doCopy<ARMCPU_ARM9>();
1961
-			else doCopy<ARMCPU_ARM7>();
1962
-			//printf(";%d\n",gxFIFO.size);
1399
+			this->running = true;
1400
+			this->paused = false;
1401
+			if (this->procnum == ARMCPU_ARM9)
1402
+				this->doCopy<ARMCPU_ARM9>();
1403
+			else
1404
+				this->doCopy<ARMCPU_ARM7>();
1963 1405
 		}
1964 1406
 	}
1965
-
1966
-	//driver->DEBUG_UpdateIORegView(BaseDriver::EDEBUG_IOREG_DMA);
1967 1407
 }
1968 1408
 
1969
-template<int PROCNUM>
1970
-void DmaController::doCopy()
1409
+template<int PROCNUM> void DmaController::doCopy()
1971 1410
 {
1972
-	//generate a copy count depending on various copy mode's behavior
1973
-	uint32_t todo = wordcount;
1974
-	if(todo == 0) todo = 0x200000; //according to gbatek.. //TODO - this should not work this way for arm7 according to gbatek
1975
-	if(startmode == EDMAMode_MemDisplay)
1411
+	// generate a copy count depending on various copy mode's behavior
1412
+	uint32_t todo = this->wordcount;
1413
+	if (PROCNUM == ARMCPU_ARM9)
1414
+		if (!todo)
1415
+			todo = 0x200000; // according to gbatek.. we've verified this behaviour on the arm7
1416
+	if (this->startmode == EDMAMode_MemDisplay)
1976 1417
 	{
1977
-		todo = 128; //this is a hack. maybe an alright one though. it should be 4 words at a time. this is a whole scanline
1418
+		todo = 128; // this is a hack. maybe an alright one though. it should be 4 words at a time. this is a whole scanline
1978 1419
 
1979
-		//apparently this dma turns off after it finishes a frame
1980
-		if(nds.VCount==191) enable = 0;
1420
+		// apparently this dma turns off after it finishes a frame
1421
+		if (nds.VCount == 191)
1422
+			this->enable = 0;
1981 1423
 	}
1982
-	if(startmode == EDMAMode_Card) todo *= 0x80;
1983
-	//if(startmode == EDMAMode_GXFifo) todo = std::min(todo,(uint32_t)112);
1424
+	if (this->startmode == EDMAMode_Card)
1425
+		todo *= 0x80;
1984 1426
 
1985
-	//determine how we're going to copy
1427
+	// determine how we're going to copy
1986 1428
 	bool bogarted = false;
1987
-	uint32_t sz = (bitWidth==EDMABitWidth_16)?2:4;
1988
-	uint32_t dstinc = 0,srcinc = 0;
1989
-	switch(dar) {
1990
-		case EDMADestinationUpdate_Increment       :  dstinc =  sz; break;
1991
-		case EDMADestinationUpdate_Decrement       :  dstinc = (uint32_t)-(int32_t)sz; break;
1992
-		case EDMADestinationUpdate_Fixed           :  dstinc =   0; break;
1993
-		case EDMADestinationUpdate_IncrementReload :  dstinc =  sz; break;
1994
-		default: bogarted = true; break;
1429
+	uint32_t sz = this->bitWidth == EDMABitWidth_16 ? 2 : 4;
1430
+	uint32_t dstinc = 0, srcinc = 0;
1431
+	switch (this->dar)
1432
+	{
1433
+		case EDMADestinationUpdate_Increment:
1434
+			dstinc = sz;
1435
+			break;
1436
+		case EDMADestinationUpdate_Decrement:
1437
+			dstinc = static_cast<uint32_t>(-static_cast<int32_t>(sz));
1438
+			break;
1439
+		case EDMADestinationUpdate_Fixed:
1440
+			dstinc = 0;
1441
+			break;
1442
+		case EDMADestinationUpdate_IncrementReload:
1443
+			dstinc = sz;
1444
+			break;
1445
+		default:
1446
+			bogarted = true;
1995 1447
 	}
1996
-	switch(sar) {
1997
-		case EDMASourceUpdate_Increment : srcinc = sz; break;
1998
-		case EDMASourceUpdate_Decrement : srcinc = (uint32_t)-(int32_t)sz; break;
1999
-		case EDMASourceUpdate_Fixed		: srcinc = 0; break;
2000
-		case EDMASourceUpdate_Invalid   : bogarted = true; break;
2001
-		default: bogarted = true; break;
1448
+	switch (this->sar)
1449
+	{
1450
+		case EDMASourceUpdate_Increment:
1451
+			srcinc = sz;
1452
+			break;
1453
+		case EDMASourceUpdate_Decrement:
1454
+			srcinc = static_cast<uint32_t>(-static_cast<int32_t>(sz));
1455
+			break;
1456
+		case EDMASourceUpdate_Fixed:
1457
+			srcinc = 0;
1458
+			break;
1459
+		case EDMASourceUpdate_Invalid:
1460
+		default:
1461
+			bogarted = true;
2002 1462
 	}
2003 1463
 
2004
-	//need to figure out what to do about this
2005
-	if(bogarted)
1464
+	// need to figure out what to do about this
1465
+	if (bogarted)
2006 1466
 	{
2007 1467
 		printf("YOUR GAME IS BOGARTED!!! PLEASE REPORT!!!\n");
2008 1468
 		assert(false);
2009 1469
 		return;
2010 1470
 	}
2011 1471
 
2012
-	uint32_t src = saddr;
2013
-	uint32_t dst = daddr;
2014
-
1472
+	uint32_t src = this->saddr;
1473
+	uint32_t dst = this->daddr;
2015 1474
 
2016
-	//if these do not use MMU_AT_DMA and the corresponding code in the read/write routines,
2017
-	//then danny phantom title screen will be filled with a garbage char which is made by
2018
-	//dmaing from 0x00000000 to 0x06000000
2019
-	//TODO - these might be losing out a lot by not going through the templated version anymore.
2020
-	//we might make another function to do just the raw copy op which can use them with checks
2021
-	//outside the loop
1475
+	// if these do not use MMU_AT_DMA and the corresponding code in the read/write routines,
1476
+	// then danny phantom title screen will be filled with a garbage char which is made by
1477
+	// dmaing from 0x00000000 to 0x06000000
1478
+	// TODO - these might be losing out a lot by not going through the templated version anymore.
1479
+	// we might make another function to do just the raw copy op which can use them with checks
1480
+	// outside the loop
2022 1481
 	int time_elapsed = 0;
2023
-	if(sz==4) {
2024
-		for(int32_t i=(int32_t)todo; i>0; i--)
1482
+	for (int32_t i = static_cast<int32_t>(todo); i > 0; --i)
1483
+	{
1484
+		if (sz == 4)
2025 1485
 		{
2026
-			time_elapsed += _MMU_accesstime<PROCNUM,MMU_AT_DMA,32,MMU_AD_READ,true>(src,true);
2027
-			time_elapsed += _MMU_accesstime<PROCNUM,MMU_AT_DMA,32,MMU_AD_WRITE,true>(dst,true);
2028
-			uint32_t temp = _MMU_read32(procnum,MMU_AT_DMA,src);
2029
-			_MMU_write32(procnum,MMU_AT_DMA,dst, temp);
2030
-			dst += dstinc;
2031
-			src += srcinc;
1486
+			time_elapsed += _MMU_accesstime<PROCNUM, MMU_AT_DMA, 32, MMU_AD_READ, true>(src, true);
1487
+			time_elapsed += _MMU_accesstime<PROCNUM, MMU_AT_DMA, 32, MMU_AD_WRITE, true>(dst, true);
1488
+			uint32_t temp = _MMU_read32(procnum, MMU_AT_DMA, src);
1489
+			_MMU_write32(procnum, MMU_AT_DMA, dst, temp);
2032 1490
 		}
2033
-	} else {
2034
-		for(int32_t i=(int32_t)todo; i>0; i--)
1491
+		else
2035 1492
 		{
2036
-			time_elapsed += _MMU_accesstime<PROCNUM,MMU_AT_DMA,16,MMU_AD_READ,true>(src,true);
2037
-			time_elapsed += _MMU_accesstime<PROCNUM,MMU_AT_DMA,16,MMU_AD_WRITE,true>(dst,true);
2038
-			uint16_t temp = _MMU_read16(procnum,MMU_AT_DMA,src);
2039
-			_MMU_write16(procnum,MMU_AT_DMA,dst, temp);
2040
-			dst += dstinc;
2041
-			src += srcinc;
1493
+			time_elapsed += _MMU_accesstime<PROCNUM, MMU_AT_DMA, 16, MMU_AD_READ, true>(src, true);
1494
+			time_elapsed += _MMU_accesstime<PROCNUM, MMU_AT_DMA, 16, MMU_AD_WRITE, true>(dst, true);
1495
+			uint16_t temp = _MMU_read16(procnum, MMU_AT_DMA, src);
1496
+			_MMU_write16(procnum, MMU_AT_DMA, dst, temp);
2042 1497
 		}
1498
+		dst += dstinc;
1499
+		src += srcinc;
2043 1500
 	}
2044 1501
 
2045
-	//reschedule an event for the end of this dma, and figure out how much it cost us
2046
-	doSchedule();
1502
+	// reschedule an event for the end of this dma, and figure out how much it cost us
1503
+	this->doSchedule();
2047 1504
 
2048 1505
 	// zeromus, check it
2049
-	if (wordcount > todo)
2050
-		nextEvent += todo/4; //TODO - surely this is a gross simplification
2051
-	//apparently moon has very, very tight timing (i didnt spy it using waitbyloop swi...)
2052
-	//so lets bump this down a bit for now,
2053
-	//(i think this code is in nintendo libraries)
2054
-
2055
-	//write back the addresses
2056
-	saddr = src;
2057
-	if(dar != EDMADestinationUpdate_IncrementReload) //but dont write back dst if we were supposed to reload
2058
-		daddr = dst;
2059
-
2060
-	//do wordcount accounting
2061
-	if(startmode == EDMAMode_Card)
2062
-		todo /= 0x80; //divide this funky one back down before subtracting it
2063
-
2064
-	if(!repeatMode)
2065
-		wordcount -= todo;
1506
+	if (this->wordcount > todo)
1507
+		this->nextEvent += todo / 4; // TODO - surely this is a gross simplification
1508
+	// apparently moon has very, very tight timing (i didnt spy it using waitbyloop swi...)
1509
+	// so lets bump this down a bit for now,
1510
+	// (i think this code is in nintendo libraries)
1511
+
1512
+	// write back the addresses
1513
+	this->saddr = src;
1514
+	if (this->dar != EDMADestinationUpdate_IncrementReload) // but dont write back dst if we were supposed to reload
1515
+		this->daddr = dst;
1516
+
1517
+	// do wordcount accounting
1518
+	if (this->startmode == EDMAMode_Card)
1519
+		todo /= 0x80; // divide this funky one back down before subtracting it
1520
+
1521
+	if (!this->repeatMode)
1522
+		this->wordcount -= todo;
2066 1523
 }
2067 1524
 
2068 1525
 void triggerDma(EDMAMode mode)
2069 1526
 {
2070 1527
 	MACRODO2(0, {
2071
-		const int i=X;
1528
+		int i = X;
2072 1529
 		MACRODO4(0, {
2073
-			const int j=X;
1530
+			int j = X;
2074 1531
 			MMU_new.dma[i][j].tryTrigger(mode);
2075 1532
 		});
2076 1533
 	});
... ...
@@ -2078,307 +1535,132 @@ void triggerDma(EDMAMode mode)
2078 1535
 
2079 1536
 void DmaController::tryTrigger(EDMAMode mode)
2080 1537
 {
2081
-	if(startmode != mode) return;
2082
-	if(!enable) return;
2083
-
2084
-	//hmm dont trigger it if its already running!
2085
-	//but paused things need triggers to continue
2086
-	if(running && !paused) return;
2087
-	triggered = true;
2088
-	doSchedule();
1538
+	if (this->startmode != mode)
1539
+		return;
1540
+	if (!this->enable)
1541
+		return;
1542
+
1543
+	// hmm dont trigger it if its already running!
1544
+	// but paused things need triggers to continue
1545
+	if (this->running && !this->paused)
1546
+		return;
1547
+	this->triggered = true;
1548
+	this->doSchedule();
2089 1549
 }
2090 1550
 
2091 1551
 void DmaController::doSchedule()
2092 1552
 {
2093
-	dmaCheck = true;
2094
-	nextEvent = nds_timer;
1553
+	this->dmaCheck = true;
1554
+	this->nextEvent = nds_timer;
2095 1555
 	NDS_RescheduleDMA();
2096 1556
 }
2097 1557
 
2098
-
2099 1558
 void DmaController::doPause()
2100 1559
 {
2101
-	triggered = false;
2102
-	paused = true;
1560
+	this->triggered = false;
1561
+	this->paused = true;
2103 1562
 }
2104 1563
 
2105 1564
 void DmaController::doStop()
2106 1565
 {
2107
-	//if(procnum==0) printf("%08lld stop type %d dma#%d\n",nds_timer,startmode,chan);
2108
-	running = false;
2109
-	if(!repeatMode) enable = false;
2110
-	if(irq) {
2111
-		NDS_makeIrq(procnum,IRQ_BIT_DMA_0+chan);
2112
-	}
1566
+	this->running = false;
1567
+	if (!this->repeatMode)
1568
+		this->enable = false;
1569
+	if (this->irq)
1570
+		NDS_makeIrq(this->procnum, IRQ_BIT_DMA_0 + this->chan);
2113 1571
 }
2114 1572
 
2115
-
2116
-
2117 1573
 uint32_t DmaController::read32()
2118 1574
 {
2119 1575
 	uint32_t ret = 0;
2120
-	ret |= enable<<31;
2121
-	ret |= irq<<30;
2122
-	ret |= _startmode<<27;
2123
-	ret |= bitWidth<<26;
2124
-	ret |= repeatMode<<25;
2125
-	ret |= sar<<23;
2126
-	ret |= dar<<21;
2127
-	ret |= wordcount;
1576
+	ret |= this->enable << 31;
1577
+	ret |= this->irq << 30;
1578
+	ret |= this->_startmode << 27;
1579
+	ret |= this->bitWidth << 26;
1580
+	ret |= this->repeatMode << 25;
1581
+	ret |= this->sar << 23;
1582
+	ret |= this->dar << 21;
1583
+	ret |= this->wordcount;
2128 1584
 	//printf("dma %d,%d READ  %08X\n",procnum,chan,ret);
2129
-	if(ret == 0xAF000001) {
2130
-		//int zzz=9;
2131
-	}
2132 1585
 	return ret;
2133 1586
 }
2134 1587
 
2135
-/*static inline void write_auxspicnt(const int, const int size, const int adr, const int val)
2136
-{
2137
-	//why val==0 to reset? is it a particular bit? its not bit 6...
2138
-	switch(size) {
2139
-		case 16:
2140
-			MMU.AUX_SPI_CNT = val;
2141
-			if (val == 0) MMU_new.backupDevice.reset_command();
2142
-			break;
2143
-		case 8:
2144
-			switch(adr) {
2145
-				case 0:
2146
-					T1WriteByte((uint8_t*)&MMU.AUX_SPI_CNT,0,val);
2147
-					if (val == 0) MMU_new.backupDevice.reset_command();
2148
-					break;
2149
-				case 1:
2150
-					T1WriteByte((uint8_t*)&MMU.AUX_SPI_CNT,1,val);
2151
-					break;
2152
-			}
2153
-	}
2154
-}*/
2155
-
2156
-
2157
-//================================================================================================== ARM9 *
2158
-//=========================================================================================================
2159
-//=========================================================================================================
2160
-//================================================= MMU write 08
1588
+// ================================================================================================== ARM9 *
1589
+// =========================================================================================================
1590
+// =========================================================================================================
1591
+// ================================================= MMU write 08
2161 1592
 void FASTCALL _MMU_ARM9_write08(uint32_t adr, uint8_t val)
2162 1593
 {
2163 1594
 	adr &= 0x0FFFFFFF;
2164 1595
 
2165
-	//mmu_log_debug_ARM9(adr, "(write08) 0x%02X", val);
2166
-
2167
-	if(adr < 0x02000000)
1596
+	if (adr < 0x02000000)
2168 1597
 	{
2169
-		T1WriteByte(MMU.ARM9_ITCM, adr&0x7FFF, val);
1598
+#ifdef HAVE_JIT
1599
+		JIT_COMPILED_FUNC_KNOWNBANK(adr, ARM9_ITCM, 0x7FFF, 0) = 0;
1600
+#endif
1601
+		T1WriteByte(MMU.ARM9_ITCM, adr & 0x7FFF, val);
2170 1602
 		return;
2171 1603
 	}
2172 1604
 
2173
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
2174
-	{
2175
-		//addon.write08(adr, val);
1605
+	if (adr >= 0x08000000 && adr < 0x0A010000)
2176 1606
 		return;
2177
-	}
2178 1607
 
2179
-	//block 8bit writes to OAM and palette memory
2180
-	if((adr&0x0F000000)==0x07000000) return;
2181
-	if((adr&0x0F000000)==0x05000000) return;
1608
+	// block 8bit writes to OAM and palette memory
1609
+	if ((adr & 0x0F000000) == 0x07000000)
1610
+		return;
1611
+	if ((adr & 0x0F000000) == 0x05000000)
1612
+		return;
2182 1613
 
2183
-	if (adr >> 24 == 4)
1614
+	if ((adr >> 24) == 4)
2184 1615
 	{
2185
-
2186
-		// TODO: add pal reg
2187
-		/*if (nds.power1.gpuMain == 0)
2188
-			if ((adr >= 0x04000008) && (adr<=0x0400005F)) return;*/
2189
-		/*if (nds.power1.gpuSub == 0)
2190
-			if ((adr >= 0x04001008) && (adr<=0x0400105F)) return;*/
2191
-		/*if (nds.power1.gfx3d_geometry == 0)
2192
-			if ((adr >= 0x04000400) && (adr<=0x040006FF)) return;
2193
-		if (nds.power1.gfx3d_render == 0)
2194
-			if ((adr >= 0x04000320) && (adr<=0x040003FF)) return;*/
2195
-
2196
-		if(MMU_new.is_dma(adr)) {
2197
-			MMU_new.write_dma(ARMCPU_ARM9,8,adr,val);
1616
+		if (MMU_new.is_dma(adr))
1617
+		{
1618
+			MMU_new.write_dma(ARMCPU_ARM9, 8, adr, val);
2198 1619
 			return;
2199 1620
 		}
2200 1621
 
2201
-		switch(adr)
1622
+		switch (adr)
2202 1623
 		{
2203
-			case REG_SQRTCNT: printf("ERROR 8bit SQRTCNT WRITE\n"); return;
2204
-			case REG_SQRTCNT+1: printf("ERROR 8bit SQRTCNT1 WRITE\n"); return;
2205
-			case REG_SQRTCNT+2: printf("ERROR 8bit SQRTCNT2 WRITE\n"); return;
2206
-			case REG_SQRTCNT+3: printf("ERROR 8bit SQRTCNT3 WRITE\n"); return;
1624
+			case REG_SQRTCNT:
1625
+				printf("ERROR 8bit SQRTCNT WRITE\n");
1626
+				return;
1627
+			case REG_SQRTCNT + 1:
1628
+				printf("ERROR 8bit SQRTCNT1 WRITE\n");
1629
+				return;
1630
+			case REG_SQRTCNT + 2:
1631
+				printf("ERROR 8bit SQRTCNT2 WRITE\n");
1632
+				return;
1633
+			case REG_SQRTCNT + 3:
1634
+				printf("ERROR 8bit SQRTCNT3 WRITE\n");
1635
+				return;
2207 1636
 
2208 1637
 #if 1
2209
-			case REG_DIVCNT: printf("ERROR 8bit DIVCNT WRITE\n"); return;
2210
-			case REG_DIVCNT+1: printf("ERROR 8bit DIVCNT1 WRITE\n"); return;
2211
-			case REG_DIVCNT+2: printf("ERROR 8bit DIVCNT2 WRITE\n"); return;
2212
-			case REG_DIVCNT+3: printf("ERROR 8bit DIVCNT3 WRITE\n"); return;
1638
+			case REG_DIVCNT:
1639
+				printf("ERROR 8bit DIVCNT WRITE\n");
1640
+				return;
1641
+			case REG_DIVCNT + 1:
1642
+				printf("ERROR 8bit DIVCNT+1 WRITE\n");
1643
+				return;
1644
+			case REG_DIVCNT + 2:
1645
+				printf("ERROR 8bit DIVCNT+2 WRITE\n");
1646
+				return;
1647
+			case REG_DIVCNT + 3:
1648
+				printf("ERROR 8bit DIVCNT+3 WRITE\n");
1649
+				return;
2213 1650
 #endif
2214 1651
 
2215
-			//fog table: only write bottom 7 bits
2216
-			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x01: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x03:
2217
-			case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x05: case eng_3D_FOG_TABLE+0x06: case eng_3D_FOG_TABLE+0x07:
2218
-			case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x09: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0B:
2219
-			case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0D: case eng_3D_FOG_TABLE+0x0E: case eng_3D_FOG_TABLE+0x0F:
2220
-			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x11: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x13:
2221
-			case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x15: case eng_3D_FOG_TABLE+0x16: case eng_3D_FOG_TABLE+0x17:
2222
-			case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x19: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1B:
2223
-			case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1D: case eng_3D_FOG_TABLE+0x1E: case eng_3D_FOG_TABLE+0x1F:
2224
-				val &= 0x7F;
2225
-				break;*/
2226
-
2227
-			//ensata putchar port
2228
-			/*case 0x04FFF000:
2229
-				if(nds.ensataEmulation)
2230
-					printf("%c",val);
1652
+			case REG_IF:
1653
+				REG_IF_WriteByte<ARMCPU_ARM9>(0, val);
2231 1654
 				break;
2232
-
2233
-			case eng_3D_GXSTAT:
2234
-				MMU_new.gxstat.write(8,adr,val);
2235
-				break;*/
2236
-
2237
-			/*case REG_DISPA_WIN0H:
2238
-				GPU_setWIN0_H1(MainScreen.gpu, val);
2239
-				break ;
2240
-			case REG_DISPA_WIN0H+1:
2241
-				GPU_setWIN0_H0 (MainScreen.gpu, val);
2242
-				break ;
2243
-			case REG_DISPA_WIN1H:
2244
-				GPU_setWIN1_H1 (MainScreen.gpu,val);
2245
-				break ;
2246
-			case REG_DISPA_WIN1H+1:
2247
-				GPU_setWIN1_H0 (MainScreen.gpu,val);
2248
-				break ; 	 */
2249
-
2250
-			/*case REG_DISPB_WIN0H:
2251
-				GPU_setWIN0_H1(SubScreen.gpu,val);
2252
-				break ;
2253
-			case REG_DISPB_WIN0H+1:
2254
-				GPU_setWIN0_H0(SubScreen.gpu,val);
2255
-				break ;
2256
-			case REG_DISPB_WIN1H:
2257
-				GPU_setWIN1_H1(SubScreen.gpu,val);
2258
-				break ;
2259
-			case REG_DISPB_WIN1H+1:
2260
-				GPU_setWIN1_H0(SubScreen.gpu,val);
2261
-				break ;*/
2262
-
2263
-			/*case REG_DISPA_WIN0V:
2264
-				GPU_setWIN0_V1(MainScreen.gpu,val) ;
2265
-				break ;
2266
-			case REG_DISPA_WIN0V+1:
2267
-				GPU_setWIN0_V0(MainScreen.gpu,val) ;
2268
-				break ;
2269
-			case REG_DISPA_WIN1V:
2270
-				GPU_setWIN1_V1(MainScreen.gpu,val) ;
2271
-				break ;
2272
-			case REG_DISPA_WIN1V+1:
2273
-				GPU_setWIN1_V0(MainScreen.gpu,val) ;
2274
-				break ; 	 */
2275
-
2276
-			/*case REG_DISPB_WIN0V:
2277
-				GPU_setWIN0_V1(SubScreen.gpu,val) ;
2278
-				break ;
2279
-			case REG_DISPB_WIN0V+1:
2280
-				GPU_setWIN0_V0(SubScreen.gpu,val) ;
2281
-				break ;
2282
-			case REG_DISPB_WIN1V:
2283
-				GPU_setWIN1_V1(SubScreen.gpu,val) ;
2284
-				break ;
2285
-			case REG_DISPB_WIN1V+1:
2286
-				GPU_setWIN1_V0(SubScreen.gpu,val) ;
2287
-				break ;*/
2288
-
2289
-			/*case REG_DISPA_WININ:
2290
-				GPU_setWININ0(MainScreen.gpu,val) ;
2291
-				break ;
2292
-			case REG_DISPA_WININ+1:
2293
-				GPU_setWININ1(MainScreen.gpu,val) ;
2294
-				break ;
2295
-			case REG_DISPA_WINOUT:
2296
-				GPU_setWINOUT(MainScreen.gpu,val) ;
2297
-				break ;
2298
-			case REG_DISPA_WINOUT+1:
2299
-				GPU_setWINOBJ(MainScreen.gpu,val);
2300
-				break ; 	 */
2301
-
2302
-			/*case REG_DISPB_WININ:
2303
-				GPU_setWININ0(SubScreen.gpu,val) ;
2304
-				break ;
2305
-			case REG_DISPB_WININ+1:
2306
-				GPU_setWININ1(SubScreen.gpu,val) ;
2307
-				break ;
2308
-			case REG_DISPB_WINOUT:
2309
-				GPU_setWINOUT(SubScreen.gpu,val) ;
2310
-				break ;
2311
-			case REG_DISPB_WINOUT+1:
2312
-				GPU_setWINOBJ(SubScreen.gpu,val) ;
2313
-				break ;*/
2314
-
2315
-			/*case REG_DISPA_BLDCNT:
2316
-				GPU_setBLDCNT_HIGH(MainScreen.gpu,val);
1655
+			case REG_IF + 1:
1656
+				REG_IF_WriteByte<ARMCPU_ARM9>(1, val);
2317 1657
 				break;
2318
-			case REG_DISPA_BLDCNT+1:
2319
-				GPU_setBLDCNT_LOW (MainScreen.gpu,val);
2320
-				break;*/
2321
-
2322
-			/*case REG_DISPB_BLDCNT:
2323
-				GPU_setBLDCNT_HIGH (SubScreen.gpu,val);
2324
-				break;
2325
-			case REG_DISPB_BLDCNT+1:
2326
-				GPU_setBLDCNT_LOW (SubScreen.gpu,val);
2327
-				break;*/
2328
-
2329
-			/*case REG_DISPA_BLDALPHA:
2330
-				MainScreen.gpu->setBLDALPHA_EVB(val);
1658
+			case REG_IF + 2:
1659
+				REG_IF_WriteByte<ARMCPU_ARM9>(2, val);
2331 1660
 				break;
2332
-			case REG_DISPA_BLDALPHA+1:
2333
-				MainScreen.gpu->setBLDALPHA_EVA(val);
2334
-				break;*/
2335
-
2336
-			/*case REG_DISPB_BLDALPHA:
2337
-				SubScreen.gpu->setBLDALPHA_EVB(val);
1661
+			case REG_IF + 3:
1662
+				REG_IF_WriteByte<ARMCPU_ARM9>(3, val);
2338 1663
 				break;
2339
-			case REG_DISPB_BLDALPHA+1:
2340
-				SubScreen.gpu->setBLDALPHA_EVA(val);
2341
-				break;*/
2342
-
2343
-			/*case REG_DISPA_BLDY:
2344
-				GPU_setBLDY_EVY(MainScreen.gpu,val) ;
2345
-				break ;
2346
-			case REG_DISPB_BLDY:
2347
-				GPU_setBLDY_EVY(SubScreen.gpu,val) ;
2348
-				break;*/
2349
-
2350
-			/*case REG_AUXSPICNT:
2351
-				write_auxspicnt(9,8,0,val);
2352
-				return;
2353
-			case REG_AUXSPICNT+1:
2354
-				write_auxspicnt(9,8,1,val);
2355
-				return;
2356
-
2357
-			case REG_AUXSPIDATA:
2358
-				if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF;
2359
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((uint8_t)val,ARMCPU_ARM9));
2360
-				MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag
2361
-				return;*/
2362
-
2363
-			case REG_WRAMCNT:
2364
-				/* Update WRAMSTAT at the ARM7 side */
2365
-				T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, val);
2366
-				break;
2367
-
2368
-            //case REG_POWCNT1: writereg_POWCNT1(8,adr,val); break;
2369
-
2370
-			//case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(8,adr,val); return;
2371
-			//case REG_DISPA_DISP3DCNT+1: writereg_DISP3DCNT(8,adr,val); return;
2372
-
2373
-			case REG_IF: REG_IF_WriteByte<ARMCPU_ARM9>(0,val); break;
2374
-			case REG_IF+1: REG_IF_WriteByte<ARMCPU_ARM9>(1,val); break;
2375
-			case REG_IF+2: REG_IF_WriteByte<ARMCPU_ARM9>(2,val); break;
2376
-			case REG_IF+3: REG_IF_WriteByte<ARMCPU_ARM9>(3,val); break;
2377
-
2378
-			/*case eng_3D_CLEAR_COLOR+0: case eng_3D_CLEAR_COLOR+1:
2379
-			case eng_3D_CLEAR_COLOR+2: case eng_3D_CLEAR_COLOR+3:
2380
-				//T1WriteByte((uint8_t*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val);
2381
-				break;*/
2382 1664
 
2383 1665
 			case REG_VRAMCNTA:
2384 1666
 			case REG_VRAMCNTB:
... ...
@@ -2387,178 +1669,77 @@ void FASTCALL _MMU_ARM9_write08(uint32_t adr, uint8_t val)
2387 1669
 			case REG_VRAMCNTE:
2388 1670
 			case REG_VRAMCNTF:
2389 1671
 			case REG_VRAMCNTG:
1672
+			case REG_WRAMCNT:
2390 1673
 			case REG_VRAMCNTH:
2391 1674
 			case REG_VRAMCNTI:
2392
-					MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val);
2393
-				break;
2394
-			/*case REG_DISPA_DISPMMEMFIFO:
2395
-			{
2396
-				DISP_FIFOsend(val);
2397
-				return;
2398
-			}*/
2399
-		#ifdef LOG_CARD
2400
-			case 0x040001A0 : /* TODO (clear): ??? */
2401
-			case 0x040001A1 :
2402
-			case 0x040001A2 :
2403
-			case 0x040001A8 :
2404
-			case 0x040001A9 :
2405
-			case 0x040001AA :
2406
-			case 0x040001AB :
2407
-			case 0x040001AC :
2408
-			case 0x040001AD :
2409
-			case 0x040001AE :
2410
-			case 0x040001AF :
2411
-						LOG("%08X : %02X\r\n", adr, val);
2412
-		#endif
2413
-
1675
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA), val);
2414 1676
 		}
2415 1677
 
2416
-		MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val;
1678
+		MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20][adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]] = val;
2417 1679
 		return;
2418 1680
 	}
2419 1681
 
2420
-	//bool unmapped = false, restricted = false;
2421
-	//adr = MMU_LCDmap<ARMCPU_ARM9>(adr, unmapped, restricted);
2422
-	//if(unmapped) return;
2423
-	//if(restricted) return; //block 8bit vram writes
1682
+#ifdef HAVE_JIT
1683
+	if (JIT_MAPPED(adr, ARMCPU_ARM9))
1684
+		JIT_COMPILED_FUNC_PREMASKED(adr, ARMCPU_ARM9, 0) = 0;
1685
+#endif
2424 1686
 
2425 1687
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
2426
-	MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val;
1688
+	MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20][adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]] = val;
2427 1689
 }
2428 1690
 
2429
-//================================================= MMU ARM9 write 16
1691
+// ================================================= MMU ARM9 write 16
2430 1692
 void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
2431 1693
 {
2432 1694
 	adr &= 0x0FFFFFFE;
2433 1695
 
2434
-	//mmu_log_debug_ARM9(adr, "(write16) 0x%04X", val);
2435
-
2436 1696
 	if (adr < 0x02000000)
2437 1697
 	{
2438
-		T1WriteWord(MMU.ARM9_ITCM, adr&0x7FFF, val);
1698
+#ifdef HAVE_JIT
1699
+		JIT_COMPILED_FUNC_KNOWNBANK(adr, ARM9_ITCM, 0x7FFF, 0) = 0;
1700
+#endif
1701
+		T1WriteWord(MMU.ARM9_ITCM, adr & 0x7FFF, val);
2439 1702
 		return;
2440 1703
 	}
2441 1704
 
2442
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
2443
-	{
2444
-		//addon.write16(adr, val);
1705
+	if (adr >= 0x08000000 && adr < 0x0A010000)
2445 1706
 		return;
2446
-	}
2447 1707
 
2448
-	if((adr >> 24) == 4)
1708
+	if ((adr >> 24) == 4)
2449 1709
 	{
2450
-		// TODO: add pal reg
2451
-		/*if (nds.power1.gpuMain == 0)
2452
-			if ((adr >= 0x04000008) && (adr<=0x0400005F)) return;*/
2453
-		/*if (nds.power1.gpuSub == 0)
2454
-			if ((adr >= 0x04001008) && (adr<=0x0400105F)) return;*/
2455
-		/*if (nds.power1.gfx3d_geometry == 0)
2456
-			if ((adr >= 0x04000400) && (adr<=0x040006FF)) return;
2457
-		if (nds.power1.gfx3d_render == 0)
2458
-			if ((adr >= 0x04000320) && (adr<=0x040003FF)) return;*/
2459
-
2460
-		if(MMU_new.is_dma(adr)) {
2461
-			if(val==0x02e9) {
2462
-				//int zzz=9;
2463
-			}
2464
-			MMU_new.write_dma(ARMCPU_ARM9,16,adr,val);
1710
+		if (MMU_new.is_dma(adr))
1711
+		{
1712
+			MMU_new.write_dma(ARMCPU_ARM9, 16, adr, val);
2465 1713
 			return;
2466 1714
 		}
2467 1715
 
2468 1716
 		switch (adr >> 4)
2469 1717
 		{
2470
-						//toon table
1718
+			// toon table
2471 1719
 			case 0x0400038:
2472 1720
 			case 0x0400039:
2473 1721
 			case 0x040003A:
2474 1722
 			case 0x040003B:
2475
-				((uint16_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF)>>1] = val;
2476
-				//gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val);
2477
-			return;
1723
+				reinterpret_cast<uint16_t *>(MMU.MMU_MEM[ARMCPU_ARM9][0x40])[(adr & 0xFFF) >> 1] = val;
1724
+				return;
2478 1725
 		}
2479 1726
 		// Address is an IO register
2480
-		switch(adr)
1727
+		switch (adr)
2481 1728
 		{
2482
-		/*case eng_3D_GXSTAT:
2483
-			MMU_new.gxstat.write(16,adr,val);
2484
-			break;*/
2485
-
2486
-		//fog table: only write bottom 7 bits
2487
-		/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x06:
2488
-		case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0E:
2489
-		case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x16:
2490
-		case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1E:
2491
-			val &= 0x7F7F;
2492
-			break;*/
2493
-
2494
-		/*case REG_DISPA_BG2XL: MainScreen.gpu->setAffineStartWord(2,0,val,0); break;
2495
-		case REG_DISPA_BG2XH: MainScreen.gpu->setAffineStartWord(2,0,val,1); break;
2496
-		case REG_DISPA_BG2YL: MainScreen.gpu->setAffineStartWord(2,1,val,0); break;
2497
-		case REG_DISPA_BG2YH: MainScreen.gpu->setAffineStartWord(2,1,val,1); break;
2498
-		case REG_DISPA_BG3XL: MainScreen.gpu->setAffineStartWord(3,0,val,0); break;
2499
-		case REG_DISPA_BG3XH: MainScreen.gpu->setAffineStartWord(3,0,val,1); break;
2500
-		case REG_DISPA_BG3YL: MainScreen.gpu->setAffineStartWord(3,1,val,0); break;
2501
-		case REG_DISPA_BG3YH: MainScreen.gpu->setAffineStartWord(3,1,val,1); break;
2502
-		case REG_DISPB_BG2XL: SubScreen.gpu->setAffineStartWord(2,0,val,0); break;
2503
-		case REG_DISPB_BG2XH: SubScreen.gpu->setAffineStartWord(2,0,val,1); break;
2504
-		case REG_DISPB_BG2YL: SubScreen.gpu->setAffineStartWord(2,1,val,0); break;
2505
-		case REG_DISPB_BG2YH: SubScreen.gpu->setAffineStartWord(2,1,val,1); break;
2506
-		case REG_DISPB_BG3XL: SubScreen.gpu->setAffineStartWord(3,0,val,0); break;
2507
-		case REG_DISPB_BG3XH: SubScreen.gpu->setAffineStartWord(3,0,val,1); break;
2508
-		case REG_DISPB_BG3YL: SubScreen.gpu->setAffineStartWord(3,1,val,0); break;
2509
-		case REG_DISPB_BG3YH: SubScreen.gpu->setAffineStartWord(3,1,val,1); break;*/
2510
-
2511
-		//case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(16,adr,val); return;
2512
-
2513
-			// Alpha test reference value - Parameters:1
2514
-			/*case eng_3D_ALPHA_TEST_REF:
2515
-			{
2516
-				((uint16_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x340>>1] = val;
2517
-				//gfx3d_glAlphaFunc(val);
2518
-				return;
2519
-			}
2520
-
2521
-			case eng_3D_CLEAR_COLOR:
2522
-			case eng_3D_CLEAR_COLOR+2:
2523
-			{
2524
-				//T1WriteWord((uint8_t*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val);
2525
-				break;
2526
-			}
2527
-
2528
-			// Clear background depth setup - Parameters:2
2529
-			case eng_3D_CLEAR_DEPTH:
2530
-			{
2531
-				((uint16_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x354>>1] = val;
2532
-				//gfx3d_glClearDepth(val);
2533
-				return;
2534
-			}
2535
-			// Fog Color - Parameters:4b
2536
-			case eng_3D_FOG_COLOR:
2537
-			{
2538
-				((uint16_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x358>>1] = val;
2539
-				//gfx3d_glFogColor(val);
2540
-				return;
2541
-			}
2542
-			case eng_3D_FOG_OFFSET:
2543
-			{
2544
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x35C>>1] = val;
2545
-				//gfx3d_glFogOffset(val);
2546
-				return;
2547
-			}*/
2548
-
2549 1729
 			case REG_DIVCNT:
2550 1730
 				MMU_new.div.write16(val);
2551 1731
 				execdiv();
2552 1732
 				return;
1733
+
2553 1734
 #if 1
2554 1735
 			case REG_DIVNUMER:
2555
-			case REG_DIVNUMER+2:
2556
-			case REG_DIVNUMER+4:
1736
+			case REG_DIVNUMER + 2:
1737
+			case REG_DIVNUMER + 4:
2557 1738
 				printf("DIV: 16 write NUMER %08X. PLEASE REPORT! \n", val);
2558 1739
 				break;
2559 1740
 			case REG_DIVDENOM:
2560
-			case REG_DIVDENOM+2:
2561
-			case REG_DIVDENOM+4:
1741
+			case REG_DIVDENOM + 2:
1742
+			case REG_DIVDENOM + 4:
2562 1743
 				printf("DIV: 16 write DENOM %08X. PLEASE REPORT! \n", val);
2563 1744
 				break;
2564 1745
 #endif
... ...
@@ -2567,131 +1748,6 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
2567 1748
 				execsqrt();
2568 1749
 				return;
2569 1750
 
2570
-			/*case REG_DISPA_BLDCNT:
2571
-				GPU_setBLDCNT(MainScreen.gpu,val) ;
2572
-				break ;
2573
-			case REG_DISPB_BLDCNT:
2574
-				GPU_setBLDCNT(SubScreen.gpu,val) ;
2575
-				break ;
2576
-			case REG_DISPA_BLDALPHA:
2577
-				MainScreen.gpu->setBLDALPHA(val);
2578
-				break ;
2579
-			case REG_DISPB_BLDALPHA:
2580
-				SubScreen.gpu->setBLDALPHA(val);
2581
-				break ;
2582
-			case REG_DISPA_BLDY:
2583
-				GPU_setBLDY_EVY(MainScreen.gpu,val) ;
2584
-				break ;
2585
-			case REG_DISPB_BLDY:
2586
-				GPU_setBLDY_EVY(SubScreen.gpu,val) ;
2587
-				break;
2588
-			case REG_DISPA_MASTERBRIGHT:
2589
-				GPU_setMasterBrightness (MainScreen.gpu, val);
2590
-				break;*/
2591
-				/*
2592
-			case REG_DISPA_MOSAIC:
2593
-				GPU_setMOSAIC(MainScreen.gpu,val) ;
2594
-				break ;
2595
-			case REG_DISPB_MOSAIC:
2596
-				GPU_setMOSAIC(SubScreen.gpu,val) ;
2597
-				break ;
2598
-				*/
2599
-			//case REG_DISPA_BG0HOFS:
2600
-			//	GPU_setBGxHOFS(0, MainScreen.gpu, val);
2601
-			//	break;
2602
-			//case REG_DISPA_BG0VOFS:
2603
-			//	GPU_setBGxVOFS(0, MainScreen.gpu, val);
2604
-			//	break;
2605
-			//case REG_DISPA_BG1HOFS:
2606
-			//	GPU_setBGxHOFS(1, MainScreen.gpu, val);
2607
-			//	break;
2608
-			//case REG_DISPA_BG1VOFS:
2609
-			//	GPU_setBGxVOFS(1, MainScreen.gpu, val);
2610
-			//	break;
2611
-			//case REG_DISPA_BG2HOFS:
2612
-			//	GPU_setBGxHOFS(2, MainScreen.gpu, val);
2613
-			//	break;
2614
-			//case REG_DISPA_BG2VOFS:
2615
-			//	GPU_setBGxVOFS(2, MainScreen.gpu, val);
2616
-			//	break;
2617
-			//case REG_DISPA_BG3HOFS:
2618
-			//	GPU_setBGxHOFS(3, MainScreen.gpu, val);
2619
-			//	break;
2620
-			//case REG_DISPA_BG3VOFS:
2621
-			//	GPU_setBGxVOFS(3, MainScreen.gpu, val);
2622
-			//	break;
2623
-
2624
-			/*case REG_DISPA_WIN0H:
2625
-				GPU_setWIN0_H (MainScreen.gpu,val) ;
2626
-				break ;
2627
-			case REG_DISPA_WIN1H:
2628
-				GPU_setWIN1_H(MainScreen.gpu,val) ;
2629
-				break ;
2630
-			case REG_DISPB_WIN0H:
2631
-				GPU_setWIN0_H(SubScreen.gpu,val) ;
2632
-				break ;
2633
-			case REG_DISPB_WIN1H:
2634
-				GPU_setWIN1_H(SubScreen.gpu,val) ;
2635
-				break ;
2636
-			case REG_DISPA_WIN0V:
2637
-				GPU_setWIN0_V(MainScreen.gpu,val) ;
2638
-				break ;
2639
-			case REG_DISPA_WIN1V:
2640
-				GPU_setWIN1_V(MainScreen.gpu,val) ;
2641
-				break ;
2642
-			case REG_DISPB_WIN0V:
2643
-				GPU_setWIN0_V(SubScreen.gpu,val) ;
2644
-				break ;
2645
-			case REG_DISPB_WIN1V:
2646
-				GPU_setWIN1_V(SubScreen.gpu,val) ;
2647
-				break ;
2648
-			case REG_DISPA_WININ:
2649
-				GPU_setWININ(MainScreen.gpu, val) ;
2650
-				break ;
2651
-			case REG_DISPA_WINOUT:
2652
-				GPU_setWINOUT16(MainScreen.gpu, val) ;
2653
-				break ; 	 */
2654
-
2655
-		/*	case REG_DISPB_BG0HOFS:
2656
-				GPU_setBGxHOFS(0, SubScreen.gpu, val);
2657
-				break;
2658
-			case REG_DISPB_BG0VOFS:
2659
-				GPU_setBGxVOFS(0, SubScreen.gpu, val);
2660
-				break;
2661
-			case REG_DISPB_BG1HOFS:
2662
-				GPU_setBGxHOFS(1, SubScreen.gpu, val);
2663
-				break;
2664
-			case REG_DISPB_BG1VOFS:
2665
-				GPU_setBGxVOFS(1, SubScreen.gpu, val);
2666
-				break;
2667
-			case REG_DISPB_BG2HOFS:
2668
-				GPU_setBGxHOFS(2, SubScreen.gpu, val);
2669
-				break;
2670
-			case REG_DISPB_BG2VOFS:
2671
-				GPU_setBGxVOFS(2, SubScreen.gpu, val);
2672
-				break;
2673
-			case REG_DISPB_BG3HOFS:
2674
-				GPU_setBGxHOFS(3, SubScreen.gpu, val);
2675
-				break;
2676
-			case REG_DISPB_BG3VOFS:
2677
-				GPU_setBGxVOFS(3, SubScreen.gpu, val);
2678
-				break;*/
2679
-
2680
-			/*case REG_DISPB_WININ:
2681
-				GPU_setWININ(SubScreen.gpu, val) ;
2682
-				break ;
2683
-			case REG_DISPB_WINOUT:
2684
-				GPU_setWINOUT16(SubScreen.gpu, val) ;
2685
-				break ;*/
2686
-
2687
-			/*case REG_DISPB_MASTERBRIGHT:
2688
-				GPU_setMasterBrightness (SubScreen.gpu, val);
2689
-				break;*/
2690
-
2691
-            /*case REG_POWCNT1:
2692
-				writereg_POWCNT1(16,adr,val);
2693
-				return;*/
2694
-
2695 1751
 			case REG_EXMEMCNT:
2696 1752
 			{
2697 1753
 				uint16_t remote_proc = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204);
... ...
@@ -2700,74 +1756,13 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
2700 1756
 				return;
2701 1757
 			}
2702 1758
 
2703
-			/*case REG_AUXSPICNT:
2704
-				write_auxspicnt(9,16,0,val);
2705
-				return;
2706
-
2707
-			case REG_AUXSPIDATA:
2708
-				if(val!=0)
2709
-				   MMU.AUX_SPI_CMD = val & 0xFF;
2710
-
2711
-				//T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val));
2712
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((uint8_t)val,ARMCPU_ARM9));
2713
-				MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag
2714
-				return;*/
2715
-
2716
-			/*case REG_DISPA_BG0CNT :
2717
-				//GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val);
2718
-				//GPU_setBGProp(MainScreen.gpu, 0, val);
2719
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x8, val);
2720
-				return;
2721
-			case REG_DISPA_BG1CNT :
2722
-				//GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val);
2723
-				//GPU_setBGProp(MainScreen.gpu, 1, val);
2724
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xA, val);
2725
-				return;
2726
-			case REG_DISPA_BG2CNT :
2727
-				//GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val);
2728
-				//GPU_setBGProp(MainScreen.gpu, 2, val);
2729
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC, val);
2730
-				return;
2731
-			case REG_DISPA_BG3CNT :
2732
-				//GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val);
2733
-				//GPU_setBGProp(MainScreen.gpu, 3, val);
2734
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xE, val);
2735
-				return;
2736
-			case REG_DISPB_BG0CNT :
2737
-				//GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val);
2738
-				//GPU_setBGProp(SubScreen.gpu, 0, val);
2739
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1008, val);
2740
-				return;
2741
-			case REG_DISPB_BG1CNT :
2742
-				//GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val);
2743
-				//GPU_setBGProp(SubScreen.gpu, 1, val);
2744
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100A, val);
2745
-				return;
2746
-			case REG_DISPB_BG2CNT :
2747
-				//GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val);
2748
-				//GPU_setBGProp(SubScreen.gpu, 2, val);
2749
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100C, val);
2750
-				return;
2751
-			case REG_DISPB_BG3CNT :
2752
-				//GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val);
2753
-				//GPU_setBGProp(SubScreen.gpu, 3, val);
2754
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100E, val);
2755
-				return;*/
2756
-
2757 1759
 			case REG_VRAMCNTA:
2758 1760
 			case REG_VRAMCNTC:
2759 1761
 			case REG_VRAMCNTE:
2760
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
2761
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), val >> 8);
2762
-				break;
2763 1762
 			case REG_VRAMCNTG:
2764
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
2765
-				/* Update WRAMSTAT at the ARM7 side */
2766
-				T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, val >> 8);
2767
-				break;
2768 1763
 			case REG_VRAMCNTH:
2769
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
2770
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), val >> 8);
1764
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA), val & 0xFF);
1765
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 1), val >> 8);
2771 1766
 				break;
2772 1767
 
2773 1768
 			case REG_IME:
... ...
@@ -2775,444 +1770,140 @@ void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
2775 1770
 				MMU.reg_IME[ARMCPU_ARM9] = val & 0x01;
2776 1771
 				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x208, val);
2777 1772
 				return;
2778
-			case REG_IE :
1773
+			case REG_IE:
2779 1774
 				NDS_Reschedule();
2780
-				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF0000) | val;
1775
+				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9] & 0xFFFF0000) | val;
2781 1776
 				return;
2782
-			case REG_IE + 2 :
1777
+			case REG_IE + 2:
2783 1778
 				NDS_Reschedule();
2784
-				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF) | (((uint32_t)val)<<16);
1779
+				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9] & 0xFFFF) | (static_cast<uint32_t>(val) << 16);
2785 1780
 				return;
2786
-			case REG_IF: REG_IF_WriteWord<ARMCPU_ARM9>(0,val); return;
2787
-			case REG_IF+2: REG_IF_WriteWord<ARMCPU_ARM9>(2,val); return;
2788
-
2789
-            case REG_IPCSYNC :
2790
-					MMU_IPCSync(ARMCPU_ARM9, val);
1781
+			case REG_IF:
1782
+				REG_IF_WriteWord<ARMCPU_ARM9>(0, val);
2791 1783
 				return;
1784
+			case REG_IF+2:
1785
+				REG_IF_WriteWord<ARMCPU_ARM9>(2, val); return;
2792 1786
 
2793
-			case REG_IPCFIFOCNT :
2794
-					IPC_FIFOcnt(ARMCPU_ARM9, val);
2795
-				return;
2796
-            case REG_TM0CNTL :
2797
-            case REG_TM1CNTL :
2798
-            case REG_TM2CNTL :
2799
-            case REG_TM3CNTL :
2800
-				MMU.timerReload[ARMCPU_ARM9][(adr>>2)&3] = val;
1787
+			case REG_IPCSYNC:
1788
+				MMU_IPCSync(ARMCPU_ARM9, val);
2801 1789
 				return;
2802
-			case REG_TM0CNTH :
2803
-			case REG_TM1CNTH :
2804
-			case REG_TM2CNTH :
2805
-			case REG_TM3CNTH :
1790
+
1791
+			case REG_IPCFIFOCNT:
1792
+				IPC_FIFOcnt(ARMCPU_ARM9, val);
1793
+				return;
1794
+			case REG_TM0CNTL:
1795
+			case REG_TM1CNTL:
1796
+			case REG_TM2CNTL:
1797
+			case REG_TM3CNTL:
1798
+				MMU.timerReload[ARMCPU_ARM9][(adr >> 2) & 3] = val;
1799
+				return;
1800
+			case REG_TM0CNTH:
1801
+			case REG_TM1CNTH:
1802
+			case REG_TM2CNTH:
1803
+			case REG_TM3CNTH:
2806 1804
 			{
2807
-				int timerIndex	= ((adr-2)>>2)&0x3;
1805
+				int timerIndex	= ((adr - 2) >> 2) & 0x3;
2808 1806
 				write_timer(ARMCPU_ARM9, timerIndex, val);
2809 1807
 				return;
2810 1808
 			}
2811 1809
 
2812
-			/*case REG_DISPA_DISPCNT :
2813
-				{
2814
-					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0) & 0xFFFF0000) | val;
2815
-					//GPU_setVideoProp(MainScreen.gpu, v);
2816
-					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, v);
2817
-					return;
2818
-				}
2819
-			case REG_DISPA_DISPCNT+2 :
2820
-				{
2821
-					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0) & 0xFFFF) | ((uint32_t) val << 16);
2822
-					//GPU_setVideoProp(MainScreen.gpu, v);
2823
-					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, v);
2824
-				}
2825
-				return;
2826
-			case REG_DISPA_DISPCAPCNT :
2827
-				{
2828
-					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64) & 0xFFFF0000) | val;
2829
-					//GPU_set_DISPCAPCNT(v);
2830
-					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64, v);
2831
-					return;
2832
-				}
2833
-			case REG_DISPA_DISPCAPCNT + 2:
2834
-				{
2835
-					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64) & 0xFFFF) | ((uint32_t)val << 16);
2836
-					//GPU_set_DISPCAPCNT(v);
2837
-					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64, v);
2838
-					return;
2839
-				}
2840
-
2841
-			case REG_DISPB_DISPCNT :
2842
-				{
2843
-					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000) & 0xFFFF0000) | val;
2844
-					//GPU_setVideoProp(SubScreen.gpu, v);
2845
-					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, v);
2846
-					return;
2847
-				}
2848
-			case REG_DISPB_DISPCNT+2 :
2849
-				{
2850
-					//emu_halt();
2851
-					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000) & 0xFFFF) | ((uint32_t) val << 16);
2852
-					//GPU_setVideoProp(SubScreen.gpu, v);
2853
-					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, v);
2854
-					return;
2855
-				}*/
2856
-
2857
-			/*case REG_DISPA_DISPMMEMFIFO:
2858
-			{
2859
-				DISP_FIFOsend(val);
2860
-				return;
2861
-			}*/
2862
-
2863
-			case REG_GCROMCTRL :
2864
-				MMU_writeToGCControl<ARMCPU_ARM9>( (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF0000) | val);
1810
+			case REG_GCROMCTRL:
1811
+				MMU_writeToGCControl<ARMCPU_ARM9>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF0000) | val);
2865 1812
 				return;
2866
-			case REG_GCROMCTRL+2 :
2867
-				MMU_writeToGCControl<ARMCPU_ARM9>( (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF) | ((uint32_t) val << 16));
1813
+			case REG_GCROMCTRL + 2:
1814
+				MMU_writeToGCControl<ARMCPU_ARM9>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF) | (static_cast<uint32_t>(val) << 16));
2868 1815
 				return;
2869 1816
 		}
2870 1817
 
2871
-		T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
1818
+		T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20], val);
2872 1819
 		return;
2873 1820
 	}
2874 1821
 
2875
-
2876 1822
 	bool unmapped, restricted;
2877
-	adr = MMU_LCDmap/*<ARMCPU_ARM9>*/(adr, unmapped, restricted);
2878
-	if(unmapped) return;
1823
+	adr = MMU_LCDmap<ARMCPU_ARM9>(adr, unmapped, restricted);
1824
+	if (unmapped)
1825
+		return;
1826
+
1827
+#ifdef HAVE_JIT
1828
+	if (JIT_MAPPED(adr, ARMCPU_ARM9))
1829
+		JIT_COMPILED_FUNC_PREMASKED(adr, ARMCPU_ARM9, 0) = 0;
1830
+#endif
2879 1831
 
2880 1832
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
2881
-	T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
1833
+	T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20], val);
2882 1834
 }
2883 1835
 
2884
-//================================================= MMU ARM9 write 32
1836
+// ================================================= MMU ARM9 write 32
2885 1837
 void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
2886 1838
 {
2887 1839
 	adr &= 0x0FFFFFFC;
2888 1840
 
2889
-	//mmu_log_debug_ARM9(adr, "(write32) 0x%08X", val);
2890
-
2891
-	if(adr<0x02000000)
2892
-	{
2893
-		T1WriteLong(MMU.ARM9_ITCM, adr&0x7FFF, val);
2894
-		return ;
2895
-	}
2896
-
2897
-
2898
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
1841
+	if (adr < 0x02000000)
2899 1842
 	{
2900
-		//addon.write32(adr, val);
1843
+#ifdef HAVE_JIT
1844
+		JIT_COMPILED_FUNC_KNOWNBANK(adr, ARM9_ITCM, 0x7FFF, 0) = 0;
1845
+		JIT_COMPILED_FUNC_KNOWNBANK(adr, ARM9_ITCM, 0x7FFF, 1) = 0;
1846
+#endif
1847
+		T1WriteLong(MMU.ARM9_ITCM, adr & 0x7FFF, val);
2901 1848
 		return;
2902 1849
 	}
2903 1850
 
2904
-	if((adr&0x0F000000)==0x05000000)
2905
-	{
2906
-		//int zzz=9;
2907
-	}
2908
-
2909
-#if 0
2910
-	if ((adr & 0xFF800000) == 0x04800000) {
2911
-		// access to non regular hw registers
2912
-		// return to not overwrite valid data
2913
-		return ;
2914
-	}
2915
-#endif
1851
+	if (adr >= 0x08000000 && adr < 0x0A010000)
1852
+		return;
2916 1853
 
2917
-	if((adr>>24)==4)
1854
+	if ((adr >> 24) == 4)
2918 1855
 	{
2919
-		// TODO: add pal reg
2920
-		/*if (nds.power1.gpuMain == 0)
2921
-			if ((adr >= 0x04000008) && (adr<=0x0400005F)) return;*/
2922
-		/*if (nds.power1.gpuSub == 0)
2923
-			if ((adr >= 0x04001008) && (adr<=0x0400105F)) return;*/
2924
-		/*if (nds.power1.gfx3d_geometry == 0)
2925
-			if ((adr >= 0x04000400) && (adr<=0x040006FF)) return;
2926
-		if (nds.power1.gfx3d_render == 0)
2927
-			if ((adr >= 0x04000320) && (adr<=0x040003FF)) return;*/
2928
-
2929
-		// MightyMax: no need to do several ifs, when only one can happen
2930
-		// switch/case instead
2931
-		// both comparison >=,< per if can be replaced by one bit comparison since
2932
-		// they are 2^4 aligned and 2^4n wide
2933
-		// this looks ugly but should reduce load on register writes, they are done as
2934
-		// lookups by the compiler
2935
-		/*switch (adr >> 4)
1856
+		if (MMU_new.is_dma(adr))
2936 1857
 		{
2937
-			case 0x400033:		//edge color table
2938
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val;
2939
-				return;
2940
-
2941
-			case 0x400038:
2942
-			case 0x400039:
2943
-			case 0x40003A:
2944
-			case 0x40003B:		//toon table
2945
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val;
2946
-				//gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val);
2947
-				return;
2948
-
2949
-			case 0x400040:
2950
-			case 0x400041:
2951
-			case 0x400042:
2952
-			case 0x400043:		// FIFO Commands
2953
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val;
2954
-				//gfx3d_sendCommandToFIFO(val);
2955
-				return;
2956
-
2957
-			case 0x400044:
2958
-			case 0x400045:
2959
-			case 0x400046:
2960
-			case 0x400047:
2961
-			case 0x400048:
2962
-			case 0x400049:
2963
-			case 0x40004A:
2964
-			case 0x40004B:
2965
-			case 0x40004C:
2966
-			case 0x40004D:
2967
-			case 0x40004E:
2968
-			case 0x40004F:
2969
-			case 0x400050:
2970
-			case 0x400051:
2971
-			case 0x400052:
2972
-			case 0x400053:
2973
-			case 0x400054:
2974
-			case 0x400055:
2975
-			case 0x400056:
2976
-			case 0x400057:
2977
-			case 0x400058:
2978
-			case 0x400059:
2979
-			case 0x40005A:
2980
-			case 0x40005B:
2981
-			case 0x40005C:		// Individual Commands
2982
-				if (gxFIFO.size > 254)
2983
-					nds.freezeBus = true;
2984
-
2985
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val;
2986
-				//gfx3d_sendCommand(adr, val);
2987
-				return;
2988
-
2989
-			default:
2990
-				break;
2991
-		}*/
2992
-
2993
-		if(MMU_new.is_dma(adr)) {
2994
-			MMU_new.write_dma(ARMCPU_ARM9,32,adr,val);
1858
+			MMU_new.write_dma(ARMCPU_ARM9, 32, adr, val);
2995 1859
 			return;
2996 1860
 		}
2997 1861
 
2998
-		switch(adr)
1862
+		switch (adr)
2999 1863
 		{
3000
-			case REG_SQRTCNT: MMU_new.sqrt.write16((uint16_t)val); return;
3001
-			case REG_DIVCNT: MMU_new.div.write16((uint16_t)val); return;
3002
-
3003
-			//case REG_POWCNT1: writereg_POWCNT1(32,adr,val); break;
3004
-
3005
-			//fog table: only write bottom 7 bits
3006
-			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0C:
3007
-			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1C:
3008
-				val &= 0x7F7F7F7F;
3009
-				break;*/
3010
-
3011
-
3012
-			//ensata handshaking port?
3013
-			/*case 0x04FFF010:
3014
-				if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_ack && val == 0x13579bdf)
3015
-					nds.ensataHandshake = ENSATA_HANDSHAKE_confirm;
3016
-				if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_confirm && val == 0xfdb97531)
3017
-				{
3018
-					printf("ENSATA HANDSHAKE COMPLETE\n");
3019
-					nds.ensataHandshake = ENSATA_HANDSHAKE_complete;
3020
-				}
3021
-				break;*/
3022
-
3023
-			//todo - these are usually write only regs (these and 1000 more)
3024
-			//shouldnt we block them from getting written? ugh
3025
-			/*case eng_3D_CLIPMTX_RESULT:
3026
-				if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_none && val==0x2468ace0)
3027
-				{
3028
-					printf("ENSATA HANDSHAKE BEGIN\n");
3029
-					nds.ensataHandshake = ENSATA_HANDSHAKE_query;
3030
-				}
3031
-				break;
3032
-
3033
-			case eng_3D_GXSTAT:
3034
-				MMU_new.gxstat.write32(val);
3035
-				break;*/
3036
-			/*case REG_DISPA_BG2XL:
3037
-				MainScreen.gpu->setAffineStart(2,0,val);
3038
-				return;
3039
-			case REG_DISPA_BG2YL:
3040
-				MainScreen.gpu->setAffineStart(2,1,val);
3041
-				return;
3042
-			case REG_DISPB_BG2XL:
3043
-				SubScreen.gpu->setAffineStart(2,0,val);
3044
-				return;
3045
-			case REG_DISPB_BG2YL:
3046
-				SubScreen.gpu->setAffineStart(2,1,val);
3047
-				return;
3048
-			case REG_DISPA_BG3XL:
3049
-				MainScreen.gpu->setAffineStart(3,0,val);
3050
-				return;
3051
-			case REG_DISPA_BG3YL:
3052
-				MainScreen.gpu->setAffineStart(3,1,val);
3053
-				return;
3054
-			case REG_DISPB_BG3XL:
3055
-				SubScreen.gpu->setAffineStart(3,0,val);
3056
-				return;
3057
-			case REG_DISPB_BG3YL:
3058
-				SubScreen.gpu->setAffineStart(3,1,val);
3059
-				return;*/
3060
-
3061
-			// Alpha test reference value - Parameters:1
3062
-			/*case eng_3D_ALPHA_TEST_REF:
3063
-			{
3064
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x340>>2] = val;
3065
-				//gfx3d_glAlphaFunc(val);
3066
-				return;
3067
-			}
3068
-
3069
-			case eng_3D_CLEAR_COLOR:
3070
-				//T1WriteLong((uint8_t*)&gfx3d.state.clearColor,0,val);
3071
-				break;
3072
-
3073
-			// Clear background depth setup - Parameters:2
3074
-			case eng_3D_CLEAR_DEPTH:
3075
-			{
3076
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x354>>2] = val;
3077
-				//gfx3d_glClearDepth(val);
3078
-				return;
3079
-			}
3080
-			// Fog Color - Parameters:4b
3081
-			case 0x04000358:
3082
-			{
3083
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x358>>2] = val;
3084
-				//gfx3d_glFogColor(val);
3085
-				return;
3086
-			}
3087
-			case 0x0400035C:
3088
-			{
3089
-				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x35C>>2] = val;
3090
-				//gfx3d_glFogOffset(val);
1864
+			case REG_SQRTCNT:
1865
+				MMU_new.sqrt.write16(static_cast<uint16_t>(val));
3091 1866
 				return;
3092
-			}*/
3093
-
3094
-			//case REG_DISPA_BG0HOFS:
3095
-			//	GPU_setBGxHOFS(0, MainScreen.gpu, val&0xFFFF);
3096
-			//	GPU_setBGxVOFS(0, MainScreen.gpu, (val>>16));
3097
-			//	break;
3098
-
3099
-			/*case REG_DISPA_WININ:
3100
-			{
3101
-				GPU_setWININ(MainScreen.gpu, val & 0xFFFF) ;
3102
-				GPU_setWINOUT16(MainScreen.gpu, (val >> 16) & 0xFFFF) ;
3103
-	            break;
3104
-			}
3105
-			case REG_DISPB_WININ:
3106
-			{
3107
-				GPU_setWININ(SubScreen.gpu, val & 0xFFFF) ;
3108
-				GPU_setWINOUT16(SubScreen.gpu, (val >> 16) & 0xFFFF) ;
3109
-	            break;
3110
-			}*/
3111
-
3112
-			/*case REG_DISPA_WIN0H:
3113
-			{
3114
-				GPU_setWIN0_H(MainScreen.gpu, val&0xFFFF);
3115
-				GPU_setWIN1_H(MainScreen.gpu, val>>16);
3116
-				break;
3117
-			}
3118
-			case REG_DISPA_WIN0V:
3119
-			{
3120
-				GPU_setWIN0_V(MainScreen.gpu, val&0xFFFF);
3121
-				GPU_setWIN1_V(MainScreen.gpu, val>>16);
3122
-				break;
3123
-			}
3124
-			case REG_DISPB_WIN0H:
3125
-			{
3126
-				GPU_setWIN0_H(SubScreen.gpu, val&0xFFFF);
3127
-				GPU_setWIN1_H(SubScreen.gpu, val>>16);
3128
-				break;
3129
-			}
3130
-			case REG_DISPB_WIN0V:
3131
-			{
3132
-				GPU_setWIN0_V(SubScreen.gpu, val&0xFFFF);
3133
-				GPU_setWIN1_V(SubScreen.gpu, val>>16);
3134
-				break;
3135
-			}*/
3136
-
3137
-			/*case REG_DISPA_MASTERBRIGHT:
3138
-				GPU_setMasterBrightness(MainScreen.gpu, val & 0xFFFF);
3139
-				break;
3140
-			case REG_DISPB_MASTERBRIGHT:
3141
-				GPU_setMasterBrightness(SubScreen.gpu, val & 0xFFFF);
3142
-				break;*/
3143
-
3144
-			/*case REG_DISPA_BLDCNT:
3145
-			{
3146
-				GPU_setBLDCNT   (MainScreen.gpu,val&0xffff);
3147
-				MainScreen.gpu->setBLDALPHA(val>>16);
3148
-				break;
3149
-			}
3150
-			case REG_DISPB_BLDCNT:
3151
-			{
3152
-				GPU_setBLDCNT   (SubScreen.gpu,val&0xffff);
3153
-				SubScreen.gpu->setBLDALPHA(val>>16);
3154
-				break;
3155
-			}*/
3156
-
3157
-			/*case REG_DISPA_BLDY:
3158
-				GPU_setBLDY_EVY(MainScreen.gpu,val&0xFFFF) ;
3159
-				break ;
3160
-			case REG_DISPB_BLDY:
3161
-				GPU_setBLDY_EVY(SubScreen.gpu,val&0xFFFF);
3162
-				break;*/
3163
-
3164
-			/*case REG_DISPA_DISPCNT :
3165
-				//GPU_setVideoProp(MainScreen.gpu, val);
3166
-				//GPULOG("MAIN INIT 32B %08X\r\n", val);
3167
-				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, val);
1867
+			case REG_DIVCNT:
1868
+				MMU_new.div.write16(static_cast<uint16_t>(val));
3168 1869
 				return;
3169 1870
 
3170
-			case REG_DISPB_DISPCNT :
3171
-				//GPU_setVideoProp(SubScreen.gpu, val);
3172
-				//GPULOG("SUB INIT 32B %08X\r\n", val);
3173
-				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, val);
3174
-				return;*/
3175
-
3176 1871
 			case REG_VRAMCNTA:
3177
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
3178
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), (val >> 8) & 0xFF);
3179
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+2), (val >> 16) & 0xFF);
3180
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+3), (val >> 24) & 0xFF);
3181
-				break;
3182 1872
 			case REG_VRAMCNTE:
3183
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
3184
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), (val >> 8) & 0xFF);
3185
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+2), (val >> 16) & 0xFF);
3186
-				/* Update WRAMSTAT at the ARM7 side */
3187
-				T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, (val >> 24) & 0xFF);
1873
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA), val & 0xFF);
1874
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 1), (val >> 8) & 0xFF);
1875
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 2), (val >> 16) & 0xFF);
1876
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 3), (val >> 24) & 0xFF);
3188 1877
 				break;
3189 1878
 			case REG_VRAMCNTH:
3190
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
3191
-				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), (val >> 8) & 0xFF);
1879
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA), val & 0xFF);
1880
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr - REG_VRAMCNTA + 1), (val >> 8) & 0xFF);
3192 1881
 				break;
3193 1882
 
3194
-			case REG_IME :
1883
+			case REG_IME:
3195 1884
 				NDS_Reschedule();
3196 1885
 				MMU.reg_IME[ARMCPU_ARM9] = val & 0x01;
3197 1886
 				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x208, val);
3198 1887
 				return;
3199 1888
 
3200
-			case REG_IE :
1889
+			case REG_IE:
3201 1890
 				NDS_Reschedule();
3202 1891
 				MMU.reg_IE[ARMCPU_ARM9] = val;
3203 1892
 				return;
3204 1893
 
3205
-			case REG_IF: REG_IF_WriteLong<ARMCPU_ARM9>(val); return;
1894
+			case REG_IF:
1895
+				REG_IF_WriteLong<ARMCPU_ARM9>(val);
1896
+				return;
3206 1897
 
3207
-            case REG_TM0CNTL:
3208
-            case REG_TM1CNTL:
3209
-            case REG_TM2CNTL:
3210
-            case REG_TM3CNTL:
1898
+			case REG_TM0CNTL:
1899
+			case REG_TM1CNTL:
1900
+			case REG_TM2CNTL:
1901
+			case REG_TM3CNTL:
3211 1902
 			{
3212
-				int timerIndex = (adr>>2)&0x3;
3213
-				MMU.timerReload[ARMCPU_ARM9][timerIndex] = (uint16_t)val;
1903
+				int timerIndex = (adr >> 2) & 0x3;
1904
+				MMU.timerReload[ARMCPU_ARM9][timerIndex] = static_cast<uint16_t>(val);
3214 1905
 				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & 0xFFF, static_cast<uint16_t>(val));
3215
-				write_timer(ARMCPU_ARM9, timerIndex, val>>16);
1906
+				write_timer(ARMCPU_ARM9, timerIndex, val >> 16);
3216 1907
 				return;
3217 1908
 			}
3218 1909
 
... ...
@@ -3220,31 +1911,31 @@ void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
3220 1911
 				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290, val);
3221 1912
 				execdiv();
3222 1913
 				return;
3223
-			case REG_DIVNUMER+4:
1914
+			case REG_DIVNUMER + 4:
3224 1915
 				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x294, val);
3225 1916
 				execdiv();
3226 1917
 				return;
3227 1918
 
3228
-            case REG_DIVDENOM :
3229
-				{
3230
-					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298, val);
3231
-					execdiv();
3232
-					return;
3233
-				}
3234
-			case REG_DIVDENOM+4 :
3235
-				{
3236
-					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x29C, val);
3237
-					execdiv();
3238
-					return;
3239
-				}
1919
+			case REG_DIVDENOM:
1920
+			{
1921
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298, val);
1922
+				execdiv();
1923
+				return;
1924
+			}
1925
+			case REG_DIVDENOM + 4:
1926
+			{
1927
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x29C, val);
1928
+				execdiv();
1929
+				return;
1930
+			}
3240 1931
 
3241
-			case REG_SQRTPARAM :
1932
+			case REG_SQRTPARAM:
3242 1933
 			{
3243 1934
 				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B8, val);
3244 1935
 				execsqrt();
3245 1936
 				return;
3246 1937
 			}
3247
-			case REG_SQRTPARAM+4 :
1938
+			case REG_SQRTPARAM + 4:
3248 1939
 			{
3249 1940
 				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2BC, val);
3250 1941
 				execsqrt();
... ...
@@ -3261,416 +1952,302 @@ void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
3261 1952
 				IPC_FIFOsend(ARMCPU_ARM9, val);
3262 1953
 				return;
3263 1954
 
3264
-
3265
-			case REG_GCROMCTRL :
1955
+			case REG_GCROMCTRL:
3266 1956
 				MMU_writeToGCControl<ARMCPU_ARM9>(val);
3267 1957
 				return;
3268
-			case REG_DISPA_DISPCAPCNT :
3269
-				//INFO("MMU write32: REG_DISPA_DISPCAPCNT 0x%X\n", val);
3270
-				//GPU_set_DISPCAPCNT(val);
1958
+			case REG_DISPA_DISPCAPCNT:
3271 1959
 				T1WriteLong(MMU.ARM9_REG, 0x64, val);
3272 1960
 				return;
3273 1961
 
3274
-			/*case REG_DISPA_BG0CNT :
3275
-				//GPU_setBGProp(MainScreen.gpu, 0, (val&0xFFFF));
3276
-				//GPU_setBGProp(MainScreen.gpu, 1, (val>>16));
3277
-				//if((val>>16)==0x400) emu_halt();
3278
-				T1WriteLong(MMU.ARM9_REG, 8, val);
3279
-				return;
3280
-			case REG_DISPA_BG2CNT :
3281
-					//GPU_setBGProp(MainScreen.gpu, 2, (val&0xFFFF));
3282
-					//GPU_setBGProp(MainScreen.gpu, 3, (val>>16));
3283
-					T1WriteLong(MMU.ARM9_REG, 0xC, val);
3284
-				return;
3285
-			case REG_DISPB_BG0CNT :
3286
-					//GPU_setBGProp(SubScreen.gpu, 0, (val&0xFFFF));
3287
-					//GPU_setBGProp(SubScreen.gpu, 1, (val>>16));
3288
-					T1WriteLong(MMU.ARM9_REG, 0x1008, val);
3289
-				return;
3290
-			case REG_DISPB_BG2CNT :
3291
-					//GPU_setBGProp(SubScreen.gpu, 2, (val&0xFFFF));
3292
-					//GPU_setBGProp(SubScreen.gpu, 3, (val>>16));
3293
-					T1WriteLong(MMU.ARM9_REG, 0x100C, val);
3294
-				return;*/
3295
-			/*case REG_DISPA_DISPMMEMFIFO:
3296
-			{
3297
-				DISP_FIFOsend(val);
3298
-				return;
3299
-			}*/
3300
-
3301
-			//case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(32,adr,val); return;
3302
-
3303 1962
 			case REG_GCDATAIN:
3304
-				slot1_device.write32(ARMCPU_ARM9, REG_GCDATAIN,val);
1963
+				slot1_device.write32(ARMCPU_ARM9, REG_GCDATAIN, val);
3305 1964
 				return;
3306 1965
 		}
3307 1966
 
3308
-		T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
1967
+		T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20], val);
3309 1968
 		return;
3310 1969
 	}
3311 1970
 
3312 1971
 	bool unmapped, restricted;
3313
-	adr = MMU_LCDmap/*<ARMCPU_ARM9>*/(adr, unmapped, restricted);
3314
-	if(unmapped) return;
1972
+	adr = MMU_LCDmap<ARMCPU_ARM9>(adr, unmapped, restricted);
1973
+	if (unmapped)
1974
+		return;
1975
+
1976
+#ifdef HAVE_JIT
1977
+	if (JIT_MAPPED(adr, ARMCPU_ARM9))
1978
+	{
1979
+		JIT_COMPILED_FUNC_PREMASKED(adr, ARMCPU_ARM9, 0) = 0;
1980
+		JIT_COMPILED_FUNC_PREMASKED(adr, ARMCPU_ARM9, 1) = 0;
1981
+	}
1982
+#endif
3315 1983
 
3316 1984
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
3317
-	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
1985
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20], val);
3318 1986
 }
3319 1987
 
3320
-//================================================= MMU ARM9 read 08
1988
+// ================================================= MMU ARM9 read 08
3321 1989
 uint8_t FASTCALL _MMU_ARM9_read08(uint32_t adr)
3322 1990
 {
3323 1991
 	adr &= 0x0FFFFFFF;
3324 1992
 
3325
-	//mmu_log_debug_ARM9(adr, "(read08) 0x%02X", MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]]);
3326
-
3327
-	if(adr<0x02000000)
3328
-		return T1ReadByte(MMU.ARM9_ITCM, adr&0x7FFF);
1993
+	if (adr<0x02000000)
1994
+		return T1ReadByte(MMU.ARM9_ITCM, adr & 0x7FFF);
3329 1995
 
3330
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3331
-		return 0/*addon.read08(adr)*/;
1996
+	if (adr >= 0x08000000 && adr < 0x0A010000)
1997
+		return 0;
3332 1998
 
3333
-	if (adr >> 24 == 4)
3334
-	{	//Address is an IO register
1999
+	if ((adr >> 24) == 4)
2000
+	{
2001
+		//Address is an IO register
3335 2002
 
3336
-		if(MMU_new.is_dma(adr)) return static_cast<uint8_t>(MMU_new.read_dma(ARMCPU_ARM9,8,adr));
2003
+		if (MMU_new.is_dma(adr))
2004
+			return static_cast<uint8_t>(MMU_new.read_dma(ARMCPU_ARM9, 8, adr));
3337 2005
 
3338
-		switch(adr)
2006
+		switch (adr)
3339 2007
 		{
3340
-			case REG_IF: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>());
3341
-			case REG_IF+1: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>()>>8);
3342
-			case REG_IF+2: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>()>>16);
3343
-			case REG_IF+3: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>()>>24);
2008
+			case REG_IF:
2009
+				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>());
2010
+			case REG_IF + 1:
2011
+				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>() >> 8);
2012
+			case REG_IF + 2:
2013
+				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>() >> 16);
2014
+			case REG_IF + 3:
2015
+				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>() >> 24);
3344 2016
 
3345
-			/*case REG_DISPA_DISPSTAT:
3346
-				break;
3347
-			case REG_DISPA_DISPSTAT+1:
3348
-				break;
3349
-			case REG_DISPx_VCOUNT: return nds.VCount & 0xFF;
3350
-			case REG_DISPx_VCOUNT+1: return (nds.VCount>>8) & 0xFF;*/
3351
-#if 0
3352
-			case REG_SQRTCNT: printf("ERROR 8bit SQRTCNT READ\n"); return 0;
3353
-			case REG_SQRTCNT+1: printf("ERROR 8bit SQRTCNT1 READ\n"); return 0;//(MMU_new.sqrt.read16() & 0xFF00)>>8;
3354
-#else
3355
-			case REG_SQRTCNT: return MMU_new.sqrt.read16() & 0xFF;
3356
-			case REG_SQRTCNT+1: return (MMU_new.sqrt.read16()>>8) & 0xFF;
3357
-#endif
3358
-			case REG_SQRTCNT+2: printf("ERROR 8bit SQRTCNT2 READ\n"); return 0;
3359
-			case REG_SQRTCNT+3: printf("ERROR 8bit SQRTCNT3 READ\n"); return 0;
3360
-#if 1
3361
-			case REG_DIVCNT: printf("ERROR 8bit DIVCNT READ\n"); return 0;
3362
-			case REG_DIVCNT+1: printf("ERROR 8bit DIVCNT1 READ\n"); return 0;
3363
-#else
3364
-			case REG_DIVCNT: return MMU_new.div.read16() & 0xFF;
3365
-			case REG_DIVCNT+1: return (MMU_new.div.read16()>>8) & 0xFF;
3366
-#endif
3367
-			case REG_DIVCNT+2: printf("ERROR 8bit DIVCNT2 READ\n"); return 0;
3368
-			case REG_DIVCNT+3: printf("ERROR 8bit DIVCNT3 READ\n"); return 0;
3369
-
3370
-			//fog table: write only
3371
-			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x01: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x03:
3372
-			case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x05: case eng_3D_FOG_TABLE+0x06: case eng_3D_FOG_TABLE+0x07:
3373
-			case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x09: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0B:
3374
-			case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0D: case eng_3D_FOG_TABLE+0x0E: case eng_3D_FOG_TABLE+0x0F:
3375
-			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x11: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x13:
3376
-			case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x15: case eng_3D_FOG_TABLE+0x16: case eng_3D_FOG_TABLE+0x17:
3377
-			case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x19: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1B:
3378
-			case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1D: case eng_3D_FOG_TABLE+0x1E: case eng_3D_FOG_TABLE+0x1F:
3379
-				return 0;*/
3380
-
3381
-			/*case REG_POWCNT1:
3382
-			case REG_POWCNT1+1:
3383
-			case REG_POWCNT1+2:
3384
-			case REG_POWCNT1+3:
3385
-				return readreg_POWCNT1(8,adr);*/
3386
-
3387
-			/*case eng_3D_GXSTAT:
3388
-				return MMU_new.gxstat.read(8,adr);*/
3389
-
3390
-			//case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(8,adr);
3391
-			//case REG_DISPA_DISP3DCNT+1: return readreg_DISP3DCNT(8,adr);
3392
-			//case REG_DISPA_DISP3DCNT+2: return readreg_DISP3DCNT(8,adr);
3393
-			//case REG_DISPA_DISP3DCNT+3: return readreg_DISP3DCNT(8,adr);
2017
+			case REG_WRAMCNT:
2018
+				return MMU.WRAMCNT;
2019
+
2020
+			case REG_SQRTCNT:
2021
+				return MMU_new.sqrt.read16() & 0xFF;
2022
+			case REG_SQRTCNT + 1:
2023
+				return (MMU_new.sqrt.read16() >> 8) & 0xFF;
2024
+
2025
+			// sqrtcnt isnt big enough for these to exist. but they'd probably return 0 so its ok
2026
+			case REG_SQRTCNT + 2:
2027
+				printf("ERROR 8bit SQRTCNT+2 READ\n");
2028
+				return 0;
2029
+			case REG_SQRTCNT + 3:
2030
+				printf("ERROR 8bit SQRTCNT+3 READ\n");
2031
+				return 0;
2032
+
2033
+			// Nostalgia's options menu requires that these work
2034
+			case REG_DIVCNT:
2035
+				return MMU_new.div.read16() & 0xFF;
2036
+			case REG_DIVCNT + 1:
2037
+				return (MMU_new.div.read16() >> 8) & 0xFF;
2038
+
2039
+			// divcnt isnt big enough for these to exist. but they'd probably return 0 so its ok
2040
+			case REG_DIVCNT + 2:
2041
+				printf("ERROR 8bit DIVCNT+2 READ\n");
2042
+				return 0;
2043
+			case REG_DIVCNT + 3:
2044
+				printf("ERROR 8bit DIVCNT+3 READ\n");
2045
+				return 0;
3394 2046
 		}
3395 2047
 	}
3396 2048
 
3397 2049
 	bool unmapped, restricted;
3398
-	adr = MMU_LCDmap/*<ARMCPU_ARM9>*/(adr, unmapped, restricted);
3399
-	if(unmapped) return 0;
2050
+	adr = MMU_LCDmap<ARMCPU_ARM9>(adr, unmapped, restricted);
2051
+	if (unmapped)
2052
+		return 0;
3400 2053
 
3401
-	return MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]];
2054
+	return MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF][adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]];
3402 2055
 }
3403 2056
 
3404
-//================================================= MMU ARM9 read 16
2057
+// ================================================= MMU ARM9 read 16
3405 2058
 uint16_t FASTCALL _MMU_ARM9_read16(uint32_t adr)
3406 2059
 {
3407 2060
 	adr &= 0x0FFFFFFE;
3408 2061
 
3409
-	//mmu_log_debug_ARM9(adr, "(read16) 0x%04X", T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]));
3410
-
3411
-	if(adr<0x02000000)
2062
+	if (adr < 0x02000000)
3412 2063
 		return T1ReadWord_guaranteedAligned(MMU.ARM9_ITCM, adr & 0x7FFE);
3413 2064
 
3414
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3415
-		return 0/*addon.read16(adr)*/;
2065
+	if (adr >= 0x08000000 && adr < 0x0A010000)
2066
+		return 0;
3416 2067
 
3417
-	if (adr >> 24 == 4)
2068
+	if ((adr >> 24) == 4)
3418 2069
 	{
3419
-		if(MMU_new.is_dma(adr)) return static_cast<uint16_t>(MMU_new.read_dma(ARMCPU_ARM9,16,adr));
2070
+		if (MMU_new.is_dma(adr))
2071
+			return static_cast<uint16_t>(MMU_new.read_dma(ARMCPU_ARM9, 16, adr));
3420 2072
 
3421 2073
 		// Address is an IO register
3422
-		switch(adr)
2074
+		switch (adr)
3423 2075
 		{
3424
-			/*case REG_DISPA_DISPSTAT:
3425
-				break;*/
2076
+			case REG_SQRTCNT:
2077
+				return MMU_new.sqrt.read16();
2078
+			// sqrtcnt isnt big enough for this to exist. but it'd probably return 0 so its ok
2079
+			case REG_SQRTCNT + 2:
2080
+				printf("ERROR 16bit SQRTCNT+2 READ\n");
2081
+				return 0;
2082
+
2083
+			case REG_DIVCNT:
2084
+				return MMU_new.div.read16();
2085
+			// divcnt isnt big enough for this to exist. but it'd probably return 0 so its ok
2086
+			case REG_DIVCNT + 2:
2087
+				printf("ERROR 16bit DIVCNT+2 READ\n");
2088
+				return 0;
3426 2089
 
3427
-			case REG_SQRTCNT: return MMU_new.sqrt.read16();
3428
-			case REG_DIVCNT: return MMU_new.div.read16();
3429
-			//case eng_3D_GXSTAT: return MMU_new.gxstat.read(16,adr);
2090
+			case REG_IME:
2091
+				return static_cast<uint16_t>(MMU.reg_IME[ARMCPU_ARM9]);
3430 2092
 
3431
-			/*case REG_DISPA_VCOUNT:
3432
-				if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_query)
3433
-				{
3434
-					nds.ensataHandshake = ENSATA_HANDSHAKE_ack;
3435
-					return 270;
3436
-				} else return nds.VCount;
2093
+			// WRAMCNT is readable but VRAMCNT is not, so just return WRAM's value
2094
+			case REG_VRAMCNTG:
2095
+				return MMU.WRAMCNT << 8;
3437 2096
 
3438
-			// ============================================= 3D
3439
-			case eng_3D_RAM_COUNT:
3440
-				return 0;
3441
-				//almost worthless for now
3442
-				//return gfx3d_GetNumPolys();
3443
-			case eng_3D_RAM_COUNT+2:
3444
-				return 0;
3445
-				//almost worthless for now
3446
-				//return gfx3d_GetNumVertex();*/
3447
-			// ============================================= 3D end
3448
-			case REG_IME :
3449
-				return (uint16_t)MMU.reg_IME[ARMCPU_ARM9];
3450
-
3451
-			case REG_IE :
3452
-				return (uint16_t)MMU.reg_IE[ARMCPU_ARM9];
3453
-			case REG_IE + 2 :
3454
-				return (uint16_t)(MMU.reg_IE[ARMCPU_ARM9]>>16);
3455
-
3456
-			case REG_IF: return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM9>());
3457
-			case REG_IF+2: return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM9>()>>16);
3458
-
3459
-			case REG_TM0CNTL :
3460
-			case REG_TM1CNTL :
3461
-			case REG_TM2CNTL :
3462
-			case REG_TM3CNTL :
3463
-				return read_timer(ARMCPU_ARM9,(adr&0xF)>>2);
2097
+			case REG_IE:
2098
+				return static_cast<uint16_t>(MMU.reg_IE[ARMCPU_ARM9]);
2099
+			case REG_IE + 2:
2100
+				return static_cast<uint16_t>(MMU.reg_IE[ARMCPU_ARM9] >> 16);
2101
+
2102
+			case REG_IF:
2103
+				return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM9>());
2104
+			case REG_IF + 2:
2105
+				return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM9>() >> 16);
2106
+
2107
+			case REG_TM0CNTL:
2108
+			case REG_TM1CNTL:
2109
+			case REG_TM2CNTL:
2110
+			case REG_TM3CNTL:
2111
+				return read_timer(ARMCPU_ARM9, (adr & 0xF) >> 2);
3464 2112
 
3465 2113
 			case REG_AUXSPICNT:
3466 2114
 				return MMU.AUX_SPI_CNT;
3467
-
3468
-            /*case REG_POWCNT1:
3469
-			case REG_POWCNT1+2:
3470
-				return readreg_POWCNT1(16,adr);*/
3471
-
3472
-			//case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(16,adr);
3473
-			//case REG_DISPA_DISP3DCNT+2: return readreg_DISP3DCNT(16,adr);
3474
-
3475
-			/*case 0x04000130:
3476
-			case 0x04000136:
3477
-				//not sure whether these should trigger from byte reads
3478
-				LagFrameFlag=0;
3479
-				break;*/
3480
-
3481
-			//fog table: write only
3482
-			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x06:
3483
-			case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0E:
3484
-			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x16:
3485
-			case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1E:
3486
-				return 0;*/
3487 2115
 		}
3488 2116
 
3489
-		return  T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
2117
+		return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]);
3490 2118
 	}
3491 2119
 
3492
-	//bool unmapped = false/*, restricted*/;
3493
-	//adr = MMU_LCDmap<ARMCPU_ARM9>(adr,unmapped, restricted);
3494
-	//if(unmapped) return 0;
3495
-
3496 2120
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF
3497 2121
 	return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]);
3498 2122
 }
3499 2123
 
3500
-//================================================= MMU ARM9 read 32
2124
+// ================================================= MMU ARM9 read 32
3501 2125
 uint32_t FASTCALL _MMU_ARM9_read32(uint32_t adr)
3502 2126
 {
3503 2127
 	adr &= 0x0FFFFFFC;
3504 2128
 
3505
-	//mmu_log_debug_ARM9(adr, "(read32) 0x%08X", T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]));
3506
-
3507
-	if(adr<0x02000000)
3508
-		return T1ReadLong_guaranteedAligned(MMU.ARM9_ITCM, adr&0x7FFC);
2129
+	if (adr < 0x02000000)
2130
+		return T1ReadLong_guaranteedAligned(MMU.ARM9_ITCM, adr & 0x7FFC);
3509 2131
 
3510
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3511
-		return 0/*addon.read32(adr)*/;
2132
+	if (adr >= 0x08000000 && adr < 0x0A010000)
2133
+		return 0;
3512 2134
 
3513 2135
 	// Address is an IO register
3514
-	if((adr >> 24) == 4)
2136
+	if ((adr >> 24) == 4)
3515 2137
 	{
3516
-		if(MMU_new.is_dma(adr)) return MMU_new.read_dma(ARMCPU_ARM9,32,adr);
2138
+		if (MMU_new.is_dma(adr))
2139
+			return MMU_new.read_dma(ARMCPU_ARM9, 32, adr);
3517 2140
 
3518
-		switch(adr)
2141
+		switch (adr)
3519 2142
 		{
3520 2143
 			case REG_DSIMODE:
3521
-				if(!nds.Is_DSI()) break;
2144
+				if (!nds.Is_DSI())
2145
+					break;
3522 2146
 				return 1;
3523 2147
 			case 0x04004008:
3524
-				if(!nds.Is_DSI()) break;
2148
+				if (!nds.Is_DSI())
2149
+					break;
3525 2150
 				return 0x8000;
3526 2151
 
3527
-			/*case REG_DISPA_DISPSTAT:
3528
-				break;
3529
-
3530
-			case REG_DISPx_VCOUNT: return nds.VCount;*/
3531
-
3532
-			//Dolphin Island Underwater Adventures uses this amidst seemingly reasonable divs so we're going to emulate it.
3533
-			case REG_DIVCNT: return MMU_new.div.read16();
3534
-			//I guess we'll do this also
3535
-			case REG_SQRTCNT: return MMU_new.sqrt.read16();
3536
-
3537
-			//fog table: write only
3538
-			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0C:
3539
-			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1C:
3540
-				return 0;*/
3541
-
3542
-			/*case eng_3D_CLIPMTX_RESULT:
3543
-			case eng_3D_CLIPMTX_RESULT+4:
3544
-			case eng_3D_CLIPMTX_RESULT+8:
3545
-			case eng_3D_CLIPMTX_RESULT+12:
3546
-			case eng_3D_CLIPMTX_RESULT+16:
3547
-			case eng_3D_CLIPMTX_RESULT+20:
3548
-			case eng_3D_CLIPMTX_RESULT+24:
3549
-			case eng_3D_CLIPMTX_RESULT+28:
3550
-			case eng_3D_CLIPMTX_RESULT+32:
3551
-			case eng_3D_CLIPMTX_RESULT+36:
3552
-			case eng_3D_CLIPMTX_RESULT+40:
3553
-			case eng_3D_CLIPMTX_RESULT+44:
3554
-			case eng_3D_CLIPMTX_RESULT+48:
3555
-			case eng_3D_CLIPMTX_RESULT+52:
3556
-			case eng_3D_CLIPMTX_RESULT+56:
3557
-			case eng_3D_CLIPMTX_RESULT+60:
3558
-			{
3559
-				//LOG("4000640h..67Fh - CLIPMTX_RESULT - Read Current Clip Coordinates Matrix (R)");
3560
-				return gfx3d_GetClipMatrix ((adr-0x04000640)/4);
3561
-			}*/
3562
-			/*case eng_3D_VECMTX_RESULT:
3563
-			case eng_3D_VECMTX_RESULT+4:
3564
-			case eng_3D_VECMTX_RESULT+8:
3565
-			case eng_3D_VECMTX_RESULT+12:
3566
-			case eng_3D_VECMTX_RESULT+16:
3567
-			case eng_3D_VECMTX_RESULT+20:
3568
-			case eng_3D_VECMTX_RESULT+24:
3569
-			case eng_3D_VECMTX_RESULT+28:
3570
-			case eng_3D_VECMTX_RESULT+32:
3571
-			{
3572
-				//LOG("4000680h..6A3h - VECMTX_RESULT - Read Current Directional Vector Matrix (R)");
3573
-				return gfx3d_GetDirectionalMatrix ((adr-0x04000680)/4);
3574
-			}*/
3575
-
3576
-			/*case eng_3D_RAM_COUNT:
3577
-			{
3578
-				return gfx3d_GetNumPolys() | ((gfx3d_GetNumVertex()) << 16);
3579
-				//LOG ("read32 - RAM_COUNT -> 0x%X", ((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF])>>2]);
3580
-			}*/
3581
-
3582
-			/*case eng_3D_POS_RESULT:
3583
-			case eng_3D_POS_RESULT+4:
3584
-			case eng_3D_POS_RESULT+8:
3585
-			case eng_3D_POS_RESULT+12:
3586
-			{
3587
-				return gfx3d_glGetPosRes((adr & 0xF) >> 2);
3588
-			}*/
3589
-			/*case eng_3D_GXSTAT:
3590
-				return MMU_new.gxstat.read(32,adr);*/
3591
-			//	======================================== 3D end
2152
+			// WRAMCNT is readable but VRAMCNT is not, so just return WRAM's value
2153
+			case REG_VRAMCNTE:
2154
+				return MMU.WRAMCNT << 24;
3592 2155
 
2156
+			// despite these being 16bit regs,
2157
+			// Dolphin Island Underwater Adventures uses this amidst seemingly reasonable divs so we're going to emulate it.
2158
+			// well, it's pretty reasonable to read them as 32bits though, isnt it?
2159
+			case REG_DIVCNT:
2160
+				return MMU_new.div.read16();
2161
+			case REG_SQRTCNT:
2162
+				return MMU_new.sqrt.read16(); // I guess we'll do this also
3593 2163
 
3594
-			case REG_IME :
2164
+			case REG_IME:
3595 2165
 				return MMU.reg_IME[ARMCPU_ARM9];
3596
-			case REG_IE :
2166
+			case REG_IE:
3597 2167
 				return MMU.reg_IE[ARMCPU_ARM9];
3598 2168
 
3599
-			case REG_IF: return MMU.gen_IF<ARMCPU_ARM9>();
2169
+			case REG_IF:
2170
+				return MMU.gen_IF<ARMCPU_ARM9>();
3600 2171
 
3601
-			case REG_IPCFIFORECV :
2172
+			case REG_IPCFIFORECV:
3602 2173
 				return IPC_FIFOrecv(ARMCPU_ARM9);
3603
-			case REG_TM0CNTL :
3604
-			case REG_TM1CNTL :
3605
-			case REG_TM2CNTL :
3606
-			case REG_TM3CNTL :
3607
-				{
3608
-					uint32_t val = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], (adr + 2) & 0xFFF);
3609
-					return MMU.timer[ARMCPU_ARM9][(adr&0xF)>>2] | (val<<16);
3610
-				}
2174
+			case REG_TM0CNTL:
2175
+			case REG_TM1CNTL:
2176
+			case REG_TM2CNTL:
2177
+			case REG_TM3CNTL:
2178
+			{
2179
+				uint32_t val = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], (adr + 2) & 0xFFF);
2180
+				return MMU.timer[ARMCPU_ARM9][(adr & 0xF) >> 2] | (val << 16);
2181
+			}
3611 2182
 
3612
-			case REG_GCDATAIN: return MMU_readFromGC<ARMCPU_ARM9>();
3613
-            //case REG_POWCNT1: return readreg_POWCNT1(32,adr);
3614
-			//case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(32,adr);
2183
+			case REG_GCDATAIN:
2184
+				return MMU_readFromGC<ARMCPU_ARM9>();
3615 2185
 		}
3616
-		return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
2186
+		return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]);
3617 2187
 	}
3618 2188
 
3619
-	//bool unmapped = false/*, restricted*/;
3620
-	//adr = MMU_LCDmap<ARMCPU_ARM9>(adr,unmapped, restricted);
3621
-	//if(unmapped) return 0;
3622
-
3623 2189
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [zeromus, inspired by shash]
3624
-	return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
2190
+	return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]);
3625 2191
 }
3626
-//================================================================================================== ARM7 *
3627
-//=========================================================================================================
3628
-//=========================================================================================================
3629
-//================================================= MMU ARM7 write 08
2192
+
2193
+// ================================================================================================== ARM7 *
2194
+// =========================================================================================================
2195
+// =========================================================================================================
2196
+// ================================================= MMU ARM7 write 08
3630 2197
 void FASTCALL _MMU_ARM7_write08(uint32_t adr, uint8_t val)
3631 2198
 {
3632 2199
 	adr &= 0x0FFFFFFF;
3633 2200
 
3634
-	//mmu_log_debug_ARM7(adr, "(write08) 0x%02X", val);
3635
-
3636
-	if (adr < 0x4000) return;	// PU BIOS
2201
+	if (adr < 0x02000000)
2202
+		return; // can't write to bios or entire area below main memory
3637 2203
 
3638
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3639
-	{
3640
-		//addon.write08(adr, val);
2204
+	if (adr >= 0x08000000 && adr < 0x0A010000)
3641 2205
 		return;
3642
-	}
3643 2206
 
3644
-	if ((adr>=0x04000400)&&(adr<0x04000520))
2207
+	if (adr >= 0x04000400 && adr < 0x04000520)
3645 2208
 	{
3646 2209
 		SPU_WriteByte(adr, val);
3647 2210
 		return;
3648
-    }
2211
+	}
3649 2212
 
3650 2213
 	if ((adr & 0xFFFF0000) == 0x04800000)
3651
-	{
3652 2214
 		/* is wifi hardware, dont intermix with regular hardware registers */
3653 2215
 		// 8-bit writes to wifi I/O and RAM are ignored
3654 2216
 		// Reference: http://nocash.emubase.de/gbatek.htm#dswifiiomap
3655 2217
 		return;
3656
-	}
3657 2218
 
3658
-	if (adr >> 24 == 4)
2219
+	if ((adr >> 24) == 4)
3659 2220
 	{
3660
-		if(MMU_new.is_dma(adr)) { MMU_new.write_dma(ARMCPU_ARM7,8,adr,val); return; }
2221
+		if (MMU_new.is_dma(adr))
2222
+		{
2223
+			MMU_new.write_dma(ARMCPU_ARM7, 8, adr, val);
2224
+			return;
2225
+		}
3661 2226
 
3662
-		switch(adr)
2227
+		switch (adr)
3663 2228
 		{
3664
-			case REG_IF: REG_IF_WriteByte<ARMCPU_ARM7>(0,val); break;
3665
-			case REG_IF+1: REG_IF_WriteByte<ARMCPU_ARM7>(1,val); break;
3666
-			case REG_IF+2: REG_IF_WriteByte<ARMCPU_ARM7>(2,val); break;
3667
-			case REG_IF+3: REG_IF_WriteByte<ARMCPU_ARM7>(3,val); break;
2229
+			case REG_IF:
2230
+				REG_IF_WriteByte<ARMCPU_ARM7>(0, val);
2231
+				break;
2232
+			case REG_IF + 1:
2233
+				REG_IF_WriteByte<ARMCPU_ARM7>(1, val);
2234
+				break;
2235
+			case REG_IF + 2:
2236
+				REG_IF_WriteByte<ARMCPU_ARM7>(2, val);
2237
+				break;
2238
+			case REG_IF + 3:
2239
+				REG_IF_WriteByte<ARMCPU_ARM7>(3, val);
2240
+				break;
3668 2241
 
3669 2242
 			case REG_POSTFLG:
2243
+				// The NDS7 register can be written to only from code executed in BIOS.
2244
+				if (NDS_ARM7.instruct_adr > 0x3FFF)
2245
+					return;
2246
+				
3670 2247
 				// hack for patched firmwares
3671 2248
 				if (val == 1)
3672 2249
 				{
3673
-					if (_MMU_ARM7_read08(REG_POSTFLG) != 0)
2250
+					if (_MMU_ARM7_read08(REG_POSTFLG))
3674 2251
 						break;
3675 2252
 					_MMU_write32<ARMCPU_ARM9>(0x27FFE24, gameInfo.header.ARM9exe);
3676 2253
 					_MMU_write32<ARMCPU_ARM7>(0x27FFE34, gameInfo.header.ARM7exe);
... ...
@@ -3679,77 +2256,56 @@ void FASTCALL _MMU_ARM7_write08(uint32_t adr, uint8_t val)
3679 2256
 
3680 2257
 			case REG_HALTCNT:
3681 2258
 				//printf("halt 0x%02X\n", val);
3682
-				switch(val)
2259
+				switch (val)
3683 2260
 				{
3684
-					case 0xC0: NDS_Sleep(); break;
3685
-					case 0x80: armcpu_Wait4IRQ(&NDS_ARM7); break;
3686
-					default: break;
2261
+					case 0xC0:
2262
+						NDS_Sleep();
2263
+						break;
2264
+					case 0x80:
2265
+						armcpu_Wait4IRQ(&NDS_ARM7);
3687 2266
 				}
3688 2267
 				break;
3689
-
3690
-			/*case REG_RTC:
3691
-				rtcWrite(val);
3692
-				return;*/
3693
-
3694
-			/*case REG_AUXSPICNT:
3695
-				write_auxspicnt(9,8,0,val);
3696
-				return;
3697
-			case REG_AUXSPICNT+1:
3698
-				write_auxspicnt(9,8,1,val);
3699
-				return;
3700
-			case REG_AUXSPIDATA:
3701
-				if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF;
3702
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((uint8_t)val,ARMCPU_ARM7));
3703
-				MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag
3704
-				return;*/
3705 2268
 		}
3706
-		MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]]=val;
2269
+		MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20][adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]] = val;
3707 2270
 		return;
3708 2271
 	}
3709 2272
 
3710
-	//bool unmapped = false/*, restricted*/;
3711
-	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
3712
-	//if(unmapped) return;
2273
+#ifdef HAVE_JIT
2274
+	if (JIT_MAPPED(adr, ARMCPU_ARM7))
2275
+		JIT_COMPILED_FUNC_PREMASKED(adr, ARMCPU_ARM7, 0) = 0;
2276
+#endif
3713 2277
 
3714 2278
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
3715
-	MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]]=val;
2279
+	MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20][adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]] = val;
3716 2280
 }
3717 2281
 
3718
-//================================================= MMU ARM7 write 16
2282
+// ================================================= MMU ARM7 write 16
3719 2283
 void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
3720 2284
 {
3721 2285
 	adr &= 0x0FFFFFFE;
3722 2286
 
3723
-	//mmu_log_debug_ARM7(adr, "(write16) 0x%04X", val);
3724
-
3725
-	if (adr < 0x4000) return;	// PU BIOS
3726
-
3727
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3728
-	{
3729
-		//addon.write16(adr, val);
3730
-		return;
3731
-	}
2287
+	if (adr < 0x02000000)
2288
+		return; // can't write to bios or entire area below main memory
3732 2289
 
3733
-	//wifi mac access
3734
-	/*if ((adr & 0xFFFF0000) == 0x04800000)
3735
-	{
3736
-		WIFI_write16(adr,val);
3737
-		T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x48], adr&MMU.MMU_MASK[ARMCPU_ARM7][0x48], val);
2290
+	if (adr >= 0x08000000 && adr < 0x0A010000)
3738 2291
 		return;
3739
-	}*/
3740 2292
 
3741
-	if ((adr>=0x04000400)&&(adr<0x04000520))
2293
+	if (adr >= 0x04000400 && adr < 0x04000520)
3742 2294
 	{
3743 2295
 		SPU_WriteWord(adr, val);
3744 2296
 		return;
3745 2297
 	}
3746 2298
 
3747
-	if((adr >> 24) == 4)
2299
+	if ((adr >> 24) == 4)
3748 2300
 	{
3749
-		if(MMU_new.is_dma(adr)) { MMU_new.write_dma(ARMCPU_ARM7,16,adr,val); return; }
2301
+		if (MMU_new.is_dma(adr))
2302
+		{
2303
+			MMU_new.write_dma(ARMCPU_ARM7, 16, adr, val);
2304
+			return;
2305
+		}
3750 2306
 
3751
-		//Address is an IO register
3752
-		switch(adr)
2307
+		// Address is an IO register
2308
+		switch (adr)
3753 2309
 		{
3754 2310
 			case REG_DISPA_VCOUNT:
3755 2311
 				if (nds.VCount >= 202 && nds.VCount <= 212)
... ...
@@ -3761,416 +2317,320 @@ void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
3761 2317
 					printf("Attempt to set VCOUNT while not within 202-212 (%i), ignored\n", nds.VCount);
3762 2318
 				return;
3763 2319
 
3764
-			/*case REG_RTC:
3765
-				rtcWrite(val);
3766
-				break;*/
3767
-
3768 2320
 			case REG_EXMEMCNT:
3769 2321
 			{
3770 2322
 				uint16_t remote_proc = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204);
3771 2323
 				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204, (val & 0x7F) | (remote_proc & 0xFF80));
2324
+				return;
3772 2325
 			}
3773
-			return;
3774
-
3775
-			/*case REG_EXTKEYIN: //readonly
3776
-				return;*/
3777 2326
 
2327
+			case REG_SPICNT:
2328
+			{
2329
+				bool reset_firmware = true;
3778 2330
 
3779
-			/*case REG_POWCNT2:
3780
-				{
3781
-					nds.power2.speakers = BIT0(val);
3782
-					nds.power2.wifi = BIT0(val);
3783
-				}
3784
-				return;*/
2331
+				if (((MMU.SPI_CNT >> 8) & 0x3) == 1 && ((val >> 8) & 0x3) == 1 && BIT11(MMU.SPI_CNT))
2332
+					// select held
2333
+					reset_firmware = false;
3785 2334
 
2335
+				//MMU.fw.com == 0; // reset fw device communication
2336
+				if (reset_firmware)
2337
+					// reset fw device communication
2338
+					fw_reset_com(&MMU.fw);
2339
+				MMU.SPI_CNT = val;
3786 2340
 
3787
-			/*case REG_AUXSPICNT:
3788
-				write_auxspicnt(7,16,0,val);
3789
-			return;
2341
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff, val);
2342
+				return;
2343
+			}
3790 2344
 
3791
-			case REG_AUXSPIDATA:
3792
-				if(val!=0)
3793
-				   MMU.AUX_SPI_CMD = val & 0xFF;
2345
+			case REG_SPIDATA:
2346
+			{
2347
+				if (val)
2348
+					MMU.SPI_CMD = val;
3794 2349
 
3795
-				//T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val));
3796
-				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((uint8_t)val,ARMCPU_ARM7));
3797
-				MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag
3798
-			return;*/
2350
+				uint16_t spicnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff);
3799 2351
 
3800
-			case REG_SPICNT :
2352
+				switch ((spicnt >> 8) & 0x3)
3801 2353
 				{
3802
-					int reset_firmware = 1;
3803
-
3804
-					if ( ((MMU.SPI_CNT >> 8) & 0x3) == 1)
2354
+					case 0:
3805 2355
 					{
3806
-						if ( ((val >> 8) & 0x3) == 1)
2356
+						if (!MMU.powerMan_CntRegWritten)
3807 2357
 						{
3808
-							if ( BIT11(MMU.SPI_CNT))
3809
-							{
3810
-								// select held
3811
-								reset_firmware = 0;
3812
-							}
2358
+							MMU.powerMan_CntReg = val & 0xFF;
2359
+							MMU.powerMan_CntRegWritten = true;
3813 2360
 						}
3814
-					}
3815
-
3816
-						//MMU.fw.com == 0; // reset fw device communication
3817
-					if ( reset_firmware)
3818
-					{
3819
-					  // reset fw device communication
3820
-					  fw_reset_com(&MMU.fw);
3821
-					}
3822
-					MMU.SPI_CNT = val;
3823
-
3824
-					T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff, val);
3825
-				}
3826
-				return;
3827
-
3828
-			case REG_SPIDATA :
3829
-				{
3830
-					uint16_t spicnt;
3831
-
3832
-					if(val!=0)
3833
-						MMU.SPI_CMD = val;
3834
-
3835
-					spicnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff);
3836
-
3837
-					switch((spicnt >> 8) & 0x3)
3838
-					{
3839
-						case 0 :
2361
+						else
2362
+						{
2363
+							uint16_t reg = MMU.powerMan_CntReg & 0x7F;
2364
+							reg &= 0x7;
2365
+							if (reg == 5 || reg == 6 || reg == 7)
2366
+								reg = 4;
2367
+
2368
+							// (let's start with emulating a DS lite, since it is the more complex case)
2369
+							if (MMU.powerMan_CntReg & 0x80)
2370
+								// read
2371
+								val = MMU.powerMan_Reg[reg];
2372
+							else
3840 2373
 							{
3841
-								if(!MMU.powerMan_CntRegWritten)
3842
-								{
3843
-									MMU.powerMan_CntReg = (val & 0xFF);
3844
-									MMU.powerMan_CntRegWritten = true;
3845
-								}
3846
-								else
3847
-								{
3848
-									uint16_t reg = MMU.powerMan_CntReg&0x7F;
3849
-									reg &= 0x7;
3850
-									if(reg==5 || reg==6 || reg==7) reg = 4;
2374
+								// write
2375
+								MMU.powerMan_Reg[reg] = static_cast<uint8_t>(val);
3851 2376
 
3852
-									//(let's start with emulating a DS lite, since it is the more complex case)
3853
-									if(MMU.powerMan_CntReg & 0x80)
3854
-									{
3855
-										//read
3856
-										val = MMU.powerMan_Reg[reg];
3857
-									}
3858
-									else
3859
-									{
3860
-										//write
3861
-										MMU.powerMan_Reg[reg] = (uint8_t)val;
3862
-
3863
-										//enum PM_Bits //from libnds
3864
-										//{
3865
-											//PM_SOUND_AMP		= BIT(0) ,   /*!< \brief Power the sound hardware (needed to hear stuff in GBA mode too) */
3866
-											//PM_SOUND_MUTE		= BIT(1),    /*!< \brief   Mute the main speakers, headphone output will still work. */
3867
-											//PM_BACKLIGHT_BOTTOM	= BIT(2),    /*!< \brief   Enable the top backlight if set */
3868
-											//PM_BACKLIGHT_TOP	= BIT(3)  ,  /*!< \brief   Enable the bottom backlight if set */
3869
-											static const uint32_t PM_SYSTEM_PWR = BIT(6);   /*!< \brief  Turn the power *off* if set */
3870
-										//};
3871
-
3872
-										//our totally pathetic register handling, only the one thing we've wanted so far
3873
-										if(MMU.powerMan_Reg[0]&PM_SYSTEM_PWR) {
3874
-											printf("SYSTEM POWERED OFF VIA ARM7 SPI POWER DEVICE\n");
3875
-											//emu_halt();
3876
-											execute = false;
3877
-										}
3878
-									}
2377
+								static const uint32_t PM_SYSTEM_PWR = BIT(6); /*!< \brief  Turn the power *off* if set */
3879 2378
 
3880
-									MMU.powerMan_CntRegWritten = false;
2379
+								// our totally pathetic register handling, only the one thing we've wanted so far
2380
+								if (MMU.powerMan_Reg[0] & PM_SYSTEM_PWR)
2381
+								{
2382
+									printf("SYSTEM POWERED OFF VIA ARM7 SPI POWER DEVICE\n");
2383
+									execute = false;
3881 2384
 								}
3882 2385
 							}
2386
+
2387
+							MMU.powerMan_CntRegWritten = false;
2388
+						}
3883 2389
 						break;
2390
+					}
3884 2391
 
3885
-						case 1 : /* firmware memory device */
3886
-							if((spicnt & 0x3) != 0)      /* check SPI baudrate (must be 4mhz) */
3887
-							{
3888
-								T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, 0);
3889
-								break;
3890
-							}
3891
-							T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, (uint8_t)val));
2392
+					case 1: /* firmware memory device */
2393
+						if (spicnt & 0x3) /* check SPI baudrate (must be 4mhz) */
2394
+						{
2395
+							T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, 0);
2396
+							break;
2397
+						}
2398
+						T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, static_cast<uint8_t>(val)));
3892 2399
 						return;
3893 2400
 
3894
-						case 2:
2401
+					case 2:
2402
+					{
2403
+						if (nds.Is_DSI())
3895 2404
 						{
3896
-							if(nds.Is_DSI())
3897
-							{
3898
-								//pass data to TSC
3899
-								val = MMU_new.dsi_tsc.write16(val);
2405
+							// pass data to TSC
2406
+							val = MMU_new.dsi_tsc.write16(val);
3900 2407
 
3901
-								//apply reset command if appropriate
3902
-								if(!BIT11(MMU.SPI_CNT))
3903
-									MMU_new.dsi_tsc.reset_command();
2408
+							// apply reset command if appropriate
2409
+							if (!BIT11(MMU.SPI_CNT))
2410
+								MMU_new.dsi_tsc.reset_command();
3904 2411
 
3905
-								break;
3906
-							}
2412
+							break;
2413
+						}
3907 2414
 
3908
-							int channel = (MMU.SPI_CMD&0x70)>>4;
3909
-							//printf("%08X\n",channel);
3910
-							switch(channel)
3911
-							{
3912
-								case TSC_MEASURE_TEMP1:
3913
-									if(spicnt & 0x800)
2415
+						int channel = (MMU.SPI_CMD & 0x70) >> 4;
2416
+						//printf("%08X\n",channel);
2417
+						switch (channel)
2418
+						{
2419
+							case TSC_MEASURE_TEMP1:
2420
+								if (spicnt & 0x800)
2421
+								{
2422
+									if (partie)
3914 2423
 									{
3915
-										if(partie)
3916
-										{
3917
-											val = ((716<<3)&0x7FF);
3918
-											partie = 0;
3919
-											break;
3920
-										}
3921
-										val = (716>>5);
3922
-										partie = 1;
2424
+										val = 1632;
2425
+										partie = 0;
3923 2426
 										break;
3924 2427
 									}
3925
-									val = ((716<<3)&0x7FF);
2428
+									val = 716 >> 5;
3926 2429
 									partie = 1;
3927 2430
 									break;
3928
-								case TSC_MEASURE_TEMP2:
3929
-									if(spicnt & 0x800)
2431
+								}
2432
+								val = 1632;
2433
+								partie = 1;
2434
+								break;
2435
+							case TSC_MEASURE_TEMP2:
2436
+								if(spicnt & 0x800)
2437
+								{
2438
+									if(partie)
3930 2439
 									{
3931
-										if(partie)
3932
-										{
3933
-											val = ((865<<3)&0x7FF);
3934
-											partie = 0;
3935
-											break;
3936
-										}
3937
-										val = (865>>5);
3938
-										partie = 1;
2440
+										val = 776;
2441
+										partie = 0;
3939 2442
 										break;
3940 2443
 									}
3941
-									val = ((865<<3)&0x7FF);
2444
+									val = 865 >> 5;
3942 2445
 									partie = 1;
3943 2446
 									break;
3944
-
3945
-								case TSC_MEASURE_Y:
2447
+								}
2448
+								val = 776;
2449
+								partie = 1;
2450
+								break;
2451
+							case TSC_MEASURE_Y:
2452
+								if (MMU.SPI_CNT & (1 << 11))
2453
+								{
2454
+									if (partie)
3946 2455
 									{
3947
-										//counter the number of adc touch coord reads and jitter it after a while to simulate a shaky human hand or multiple reads
3948
-										/*nds.adc_jitterctr++;
3949
-										if(nds.adc_jitterctr == 25)
3950
-										{
3951
-											nds.adc_jitterctr = 0;
3952
-											nds.adc_touchY ^= 16;
3953
-											nds.adc_touchX ^= 16;
3954
-										}*/
3955
-										if(MMU.SPI_CNT&(1<<11))
3956
-										{
3957
-											if(partie)
3958
-											{
3959
-												//val = (nds.adc_touchY<<3) & 0xFF;
3960
-												partie = 0;
3961
-												break;
3962
-											}
3963
-
3964
-											//val = (nds.adc_touchY>>5) & 0xFF;
3965
-											partie = 1;
3966
-											break;
3967
-										}
3968
-										//val = (nds.adc_touchY<<3)&0xFF;
3969
-										partie = 1;
2456
+										partie = 0;
3970 2457
 										break;
3971 2458
 									}
3972
-								case TSC_MEASURE_Z1: //Z1
3973
-									//used for pressure calculation - must be nonzero or else some softwares will think the stylus is up.
3974
-									//something is wrong in here and some of these LSB dont make it back to libnds... whatever.
3975
-									/*{
3976
-										u16 scratch;
3977
-										CalculateTouchPressure(CommonSettings.StylusPressure,val,scratch);
3978
-									}*/
3979
-									if(spicnt & 0x800)
2459
+									partie = 1;
2460
+									break;
2461
+								}
2462
+								partie = 1;
2463
+								break;
2464
+							case TSC_MEASURE_Z1: // Z1
2465
+								if (spicnt & 0x800)
2466
+								{
2467
+									if (partie)
3980 2468
 									{
3981
-										if(partie)
3982
-										{
3983
-											val = ((val<<3)&0x7FF);
3984
-											partie = 0;
3985
-											break;
3986
-										}
3987
-										val = (val>>5);
3988
-										partie = 1;
2469
+										val = (val << 3) & 0x7FF;
2470
+										partie = 0;
3989 2471
 										break;
3990 2472
 									}
3991
-									val = ((val<<3)&0x7FF);
2473
+									val >>= 5;
3992 2474
 									partie = 1;
3993 2475
 									break;
3994
-								case TSC_MEASURE_Z2: //Z2
3995
-									//used for pressure calculation - must be nonzero or else some softwares will think the stylus is up.
3996
-									//something is wrong in here and some of these LSB dont make it back to libnds... whatever.
3997
-									/*{
3998
-										u16 scratch;
3999
-										CalculateTouchPressure(CommonSettings.StylusPressure,scratch,val);
4000
-									}*/
4001
-									if(spicnt & 0x800)
2476
+								}
2477
+								val = (val << 3) & 0x7FF;
2478
+								partie = 1;
2479
+								break;
2480
+							case TSC_MEASURE_Z2: // Z2
2481
+								if (spicnt & 0x800)
2482
+								{
2483
+									if (partie)
4002 2484
 									{
4003
-										if(partie)
4004
-										{
4005
-											val = ((val<<3)&0x7FF);
4006
-											partie = 0;
4007
-											break;
4008
-										}
4009
-										val = (val>>5);
4010
-										partie = 1;
2485
+										val = (val << 3) & 0x7FF;
2486
+										partie = 0;
4011 2487
 										break;
4012 2488
 									}
4013
-									val = ((val<<3)&0x7FF);
2489
+									val >>= 5;
4014 2490
 									partie = 1;
4015 2491
 									break;
4016
-								case TSC_MEASURE_X:
4017
-									if(spicnt & 0x800)
2492
+								}
2493
+								val = (val << 3) & 0x7FF;
2494
+								partie = 1;
2495
+								break;
2496
+							case TSC_MEASURE_X:
2497
+								if (spicnt & 0x800)
2498
+								{
2499
+									if (partie)
4018 2500
 									{
4019
-										if(partie)
4020
-										{
4021
-											//val = (nds.adc_touchX << 3) & 0xFF;
4022
-											partie = 0;
4023
-											break;
4024
-										}
4025
-										//val = (nds.adc_touchX>>5) & 0xFF;
4026
-										partie = 1;
2501
+										partie = 0;
4027 2502
 										break;
4028 2503
 									}
4029
-									//val = (nds.adc_touchX<<3) & 0xFF;
4030 2504
 									partie = 1;
4031 2505
 									break;
4032
-								case TSC_MEASURE_AUX:
4033
-									/*if(!(val & 0x80))
4034
-										val = (Mic_ReadSample() & 0xFF);
4035
-									else*/
4036
-										val = 0;
4037
-									break;
4038
-							}
4039
-							break;
2506
+								}
2507
+								partie = 1;
4040 2508
 						}
4041
-
4042
-						case 3 :
4043
-						/* NOTICE: Device 3 of SPI is reserved (unused and unusable) */
4044
-						break;
4045 2509
 					}
4046 2510
 				}
4047 2511
 
4048 2512
 				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, val);
4049 2513
 				return;
2514
+			}
4050 2515
 
4051
-				/* NOTICE: Perhaps we have to use gbatek-like reg names instead of libnds-like ones ...*/
2516
+			/* NOTICE: Perhaps we have to use gbatek-like reg names instead of libnds-like ones ...*/
4052 2517
 
4053
-			case REG_IME :
2518
+			case REG_IME:
4054 2519
 				NDS_Reschedule();
4055 2520
 				MMU.reg_IME[ARMCPU_ARM7] = val & 0x01;
4056 2521
 				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x208, val);
4057 2522
 				return;
4058
-			case REG_IE :
2523
+			case REG_IE:
4059 2524
 				NDS_Reschedule();
4060
-				MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF0000) | val;
2525
+				MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7] & 0xFFFF0000) | val;
4061 2526
 				return;
4062
-			case REG_IE + 2 :
2527
+			case REG_IE + 2:
4063 2528
 				NDS_Reschedule();
4064
-				//emu_halt();
4065
-				MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF) | (((uint32_t)val)<<16);
2529
+				MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7] & 0xFFFF) | (static_cast<uint32_t>(val) << 16);
4066 2530
 				return;
4067 2531
 
4068
-			case REG_IF: REG_IF_WriteWord<ARMCPU_ARM7>(0,val); return;
4069
-			case REG_IF+2: REG_IF_WriteWord<ARMCPU_ARM7>(2,val); return;
2532
+			case REG_IF:
2533
+				REG_IF_WriteWord<ARMCPU_ARM7>(0, val);
2534
+				return;
2535
+			case REG_IF + 2:
2536
+				REG_IF_WriteWord<ARMCPU_ARM7>(2, val);
2537
+				return;
4070 2538
 
4071
-            case REG_IPCSYNC :
2539
+			case REG_IPCSYNC:
4072 2540
 				MMU_IPCSync(ARMCPU_ARM7, val);
4073 2541
 				return;
4074 2542
 
4075
-			case REG_IPCFIFOCNT :
2543
+			case REG_IPCFIFOCNT:
4076 2544
 				IPC_FIFOcnt(ARMCPU_ARM7, val);
4077 2545
 				return;
4078
-            case REG_TM0CNTL :
4079
-            case REG_TM1CNTL :
4080
-            case REG_TM2CNTL :
4081
-            case REG_TM3CNTL :
4082
-				MMU.timerReload[ARMCPU_ARM7][(adr>>2)&3] = val;
2546
+			case REG_TM0CNTL:
2547
+			case REG_TM1CNTL:
2548
+			case REG_TM2CNTL:
2549
+			case REG_TM3CNTL:
2550
+				MMU.timerReload[ARMCPU_ARM7][(adr >> 2) & 3] = val;
4083 2551
 				return;
4084
-			case REG_TM0CNTH :
4085
-			case REG_TM1CNTH :
4086
-			case REG_TM2CNTH :
4087
-			case REG_TM3CNTH :
2552
+			case REG_TM0CNTH:
2553
+			case REG_TM1CNTH:
2554
+			case REG_TM2CNTH:
2555
+			case REG_TM3CNTH:
4088 2556
 			{
4089
-				int timerIndex	= ((adr-2)>>2)&0x3;
2557
+				int timerIndex	= ((adr - 2) >> 2) & 0x3;
4090 2558
 				write_timer(ARMCPU_ARM7, timerIndex, val);
4091 2559
 				return;
4092 2560
 			}
4093 2561
 
4094
-			case REG_GCROMCTRL :
4095
-				MMU_writeToGCControl<ARMCPU_ARM7>( (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF0000) | val);
2562
+			case REG_GCROMCTRL:
2563
+				MMU_writeToGCControl<ARMCPU_ARM7>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF0000) | val);
4096 2564
 				return;
4097
-			case REG_GCROMCTRL+2 :
4098
-				MMU_writeToGCControl<ARMCPU_ARM7>( (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF) | ((uint32_t) val << 16));
2565
+			case REG_GCROMCTRL + 2:
2566
+				MMU_writeToGCControl<ARMCPU_ARM7>((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF) | (static_cast<uint32_t>(val) << 16));
4099 2567
 				return;
4100 2568
 		}
4101 2569
 
4102
-		T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
2570
+		T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20], val);
4103 2571
 		return;
4104 2572
 	}
4105 2573
 
4106
-	//bool unmapped = false/*, restricted*/;
4107
-	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4108
-	//if(unmapped) return;
2574
+#ifdef HAVE_JIT
2575
+	if (JIT_MAPPED(adr, ARMCPU_ARM7))
2576
+		JIT_COMPILED_FUNC_PREMASKED(adr, ARMCPU_ARM7, 0) = 0;
2577
+#endif
4109 2578
 
4110 2579
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
4111
-	T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
2580
+	T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20], val);
4112 2581
 }
4113
-//================================================= MMU ARM7 write 32
2582
+
2583
+// ================================================= MMU ARM7 write 32
4114 2584
 void FASTCALL _MMU_ARM7_write32(uint32_t adr, uint32_t val)
4115 2585
 {
4116 2586
 	adr &= 0x0FFFFFFC;
4117 2587
 
4118
-	//mmu_log_debug_ARM7(adr, "(write32) 0x%08X", val);
4119
-
4120
-	if (adr < 0x4000) return;	// PU BIOS
2588
+	if (adr < 0x02000000)
2589
+		return; // can't write to bios or entire area below main memory
4121 2590
 
4122
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
4123
-	{
4124
-		//addon.write32(adr, val);
2591
+	if (adr >= 0x08000000 && adr < 0x0A010000)
4125 2592
 		return;
4126
-	}
4127 2593
 
4128
-	/*if ((adr & 0xFFFF0000) == 0x04800000)
2594
+	if (adr >= 0x04000400 && adr < 0x04000520)
4129 2595
 	{
4130
-		WIFI_write16(adr, val & 0xFFFF);
4131
-		WIFI_write16(adr+2, val >> 16);
4132
-		T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x48], adr&MMU.MMU_MASK[ARMCPU_ARM7][0x48], val);
2596
+		SPU_WriteLong(adr, val);
4133 2597
 		return;
4134
-	}*/
4135
-
4136
-    if ((adr>=0x04000400)&&(adr<0x04000520))
4137
-    {
4138
-        SPU_WriteLong(adr, val);
4139
-        return;
4140
-    }
2598
+	}
4141 2599
 
4142
-	if((adr>>24)==4)
2600
+	if ((adr >> 24) == 4)
4143 2601
 	{
4144
-		if(MMU_new.is_dma(adr)) { MMU_new.write_dma(ARMCPU_ARM7,32,adr,val); return; }
4145
-
4146
-		switch(adr)
2602
+		if (MMU_new.is_dma(adr))
4147 2603
 		{
4148
-			/*case REG_RTC:
4149
-				rtcWrite((uint16_t)val);
4150
-				break;*/
2604
+			MMU_new.write_dma(ARMCPU_ARM7, 32, adr, val);
2605
+			return;
2606
+		}
4151 2607
 
4152
-			case REG_IME :
2608
+		switch (adr)
2609
+		{
2610
+			case REG_IME:
4153 2611
 				NDS_Reschedule();
4154 2612
 				MMU.reg_IME[ARMCPU_ARM7] = val & 0x01;
4155 2613
 				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x208, val);
4156 2614
 				return;
4157 2615
 
4158
-			case REG_IE :
2616
+			case REG_IE:
4159 2617
 				NDS_Reschedule();
4160 2618
 				MMU.reg_IE[ARMCPU_ARM7] = val;
4161 2619
 				return;
4162 2620
 
4163
-			case REG_IF: REG_IF_WriteLong<ARMCPU_ARM7>(val); return;
2621
+			case REG_IF:
2622
+				REG_IF_WriteLong<ARMCPU_ARM7>(val);
2623
+				return;
4164 2624
 
4165
-            case REG_TM0CNTL:
4166
-            case REG_TM1CNTL:
4167
-            case REG_TM2CNTL:
4168
-            case REG_TM3CNTL:
2625
+			case REG_TM0CNTL:
2626
+			case REG_TM1CNTL:
2627
+			case REG_TM2CNTL:
2628
+			case REG_TM3CNTL:
4169 2629
 			{
4170
-				int timerIndex = (adr>>2)&0x3;
4171
-				MMU.timerReload[ARMCPU_ARM7][timerIndex] = (uint16_t)val;
2630
+				int timerIndex = (adr >> 2) & 0x3;
2631
+				MMU.timerReload[ARMCPU_ARM7][timerIndex] = static_cast<uint16_t>(val);
4172 2632
 				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & 0xFFF, static_cast<uint16_t>(val));
4173
-				write_timer(ARMCPU_ARM7, timerIndex, val>>16);
2633
+				write_timer(ARMCPU_ARM7, timerIndex, val >> 16);
4174 2634
 				return;
4175 2635
 			}
4176 2636
 
... ...
@@ -4184,7 +2644,7 @@ void FASTCALL _MMU_ARM7_write32(uint32_t adr, uint32_t val)
4184 2644
 				IPC_FIFOsend(ARMCPU_ARM7, val);
4185 2645
 				return;
4186 2646
 
4187
-			case REG_GCROMCTRL :
2647
+			case REG_GCROMCTRL:
4188 2648
 				MMU_writeToGCControl<ARMCPU_ARM7>(val);
4189 2649
 				return;
4190 2650
 
... ...
@@ -4192,572 +2652,190 @@ void FASTCALL _MMU_ARM7_write32(uint32_t adr, uint32_t val)
4192 2652
 				slot1_device.write32(ARMCPU_ARM7, REG_GCDATAIN,val);
4193 2653
 				return;
4194 2654
 		}
4195
-		T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
2655
+		T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20], val);
4196 2656
 		return;
4197 2657
 	}
4198 2658
 
4199
-	//bool unmapped = false/*, restricted*/;
4200
-	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4201
-	//if(unmapped) return;
2659
+#ifdef HAVE_JIT
2660
+	if (JIT_MAPPED(adr, ARMCPU_ARM7))
2661
+	{
2662
+		JIT_COMPILED_FUNC_PREMASKED(adr, ARMCPU_ARM7, 0) = 0;
2663
+		JIT_COMPILED_FUNC_PREMASKED(adr, ARMCPU_ARM7, 1) = 0;
2664
+	}
2665
+#endif
4202 2666
 
4203 2667
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
4204
-	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
2668
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20], val);
4205 2669
 }
4206 2670
 
4207
-//================================================= MMU ARM7 read 08
2671
+// ================================================= MMU ARM7 read 08
4208 2672
 uint8_t FASTCALL _MMU_ARM7_read08(uint32_t adr)
4209 2673
 {
4210 2674
 	adr &= 0x0FFFFFFF;
4211 2675
 
4212
-	//mmu_log_debug_ARM7(adr, "(read08) 0x%02X", MMU.MMU_MEM[ARMCPU_ARM7][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM7][(adr>>20)&0xFF]]);
4213
-
4214 2676
 	if (adr < 0x4000)
4215 2677
 	{
4216
-		//uint32_t prot = T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x04000308 & MMU.MMU_MASK[ARMCPU_ARM7][0x40]);
4217
-		//if (prot) INFO("MMU7 read 08 at 0x%08X (PC 0x%08X) BIOSPROT address 0x%08X\n", adr, NDS_ARM7.R[15], prot);
4218
-
4219
-		//How accurate is this? our R[15] may not be exactly what the hardware uses (may use something less by up to 0x08)
4220
-		//This may be inaccurate at the very edge cases.
4221
-		if (NDS_ARM7.R[15] > 0x3FFF)
2678
+		// How accurate is this? our R[15] may not be exactly what the hardware uses (may use something less by up to 0x08)
2679
+		// This may be inaccurate at the very edge cases.
2680
+		if (NDS_ARM7.instruct_adr > 0x3FFF)
4222 2681
 			return 0xFF;
4223 2682
 	}
4224 2683
 
4225
-	// wifi mac access
4226
-	/*if ((adr & 0xFFFF0000) == 0x04800000)
4227
-	{
4228
-		if (adr & 1)
4229
-			return (WIFI_read16(adr-1) >> 8) & 0xFF;
4230
-		else
4231
-			return WIFI_read16(adr) & 0xFF;
4232
-	}*/
4233
-
4234
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
4235
-		return 0/*addon.read08(adr)*/;
4236
-
4237
-    if ((adr>=0x04000400)&&(adr<0x04000520))
4238
-    {
4239
-        return SPU_ReadByte(adr);
4240
-    }
2684
+	if (adr >= 0x08000000 && adr < 0x0A010000)
2685
+		return 0;
4241 2686
 
4242
-	//if (adr == REG_RTC) return (uint8_t)rtcRead();
2687
+	if (adr >= 0x04000400 && adr < 0x04000520)
2688
+		return SPU_ReadByte(adr);
4243 2689
 
4244
-	if (adr >> 24 == 4)
2690
+	if ((adr >> 24) == 4)
4245 2691
 	{
4246
-		if(MMU_new.is_dma(adr)) return static_cast<uint8_t>(MMU_new.read_dma(ARMCPU_ARM7,8,adr));
2692
+		if (MMU_new.is_dma(adr))
2693
+			return static_cast<uint8_t>(MMU_new.read_dma(ARMCPU_ARM7, 8, adr));
4247 2694
 
4248 2695
 		// Address is an IO register
4249 2696
 
4250
-		switch(adr)
2697
+		switch (adr)
4251 2698
 		{
4252
-			case REG_IF: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>());
4253
-			case REG_IF+1: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>()>>8);
4254
-			case REG_IF+2: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>()>>16);
4255
-			case REG_IF+3: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>()>>24);
4256
-
4257
-			/*case REG_DISPx_VCOUNT: return nds.VCount&0xFF;
4258
-			case REG_DISPx_VCOUNT+1: return (nds.VCount>>8)&0xFF;*/
2699
+			case REG_IF:
2700
+				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>());
2701
+			case REG_IF + 1:
2702
+				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>() >> 8);
2703
+			case REG_IF + 2:
2704
+				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>() >> 16);
2705
+			case REG_IF + 3:
2706
+				return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>() >> 24);
2707
+
2708
+			case REG_WRAMSTAT:
2709
+				return MMU.WRAMCNT;
4259 2710
 		}
4260 2711
 
4261
-		return MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]];
2712
+		return MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20][adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]];
4262 2713
 	}
4263 2714
 
4264
-	//bool unmapped = false/*, restricted*/;
4265
-	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4266
-	//if(unmapped) return 0;
4267
-
4268
-    return MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]];
2715
+	return MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20][adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]];
4269 2716
 }
4270
-//================================================= MMU ARM7 read 16
2717
+
2718
+// ================================================= MMU ARM7 read 16
4271 2719
 uint16_t FASTCALL _MMU_ARM7_read16(uint32_t adr)
4272 2720
 {
4273 2721
 	adr &= 0x0FFFFFFE;
4274 2722
 
4275
-	//mmu_log_debug_ARM7(adr, "(read16) 0x%04X", T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(adr>>20)&0xFF], adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr>>20)&0xFF]));
4276
-
4277 2723
 	if (adr < 0x4000)
4278 2724
 	{
4279
-		//uint32_t prot = T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x04000308 & MMU.MMU_MASK[ARMCPU_ARM7][0x40]);
4280
-		//if (prot) INFO("MMU7 read 16 at 0x%08X (PC 0x%08X) BIOSPROT address 0x%08X\n", adr, NDS_ARM7.R[15], prot);
4281
-		if (NDS_ARM7.R[15] > 0x3FFF)
2725
+		if (NDS_ARM7.instruct_adr > 0x3FFF)
4282 2726
 			return 0xFFFF;
4283 2727
 	}
4284 2728
 
4285
-	//wifi mac access
4286
-	/*if ((adr & 0xFFFF0000) == 0x04800000)
4287
-		return WIFI_read16(adr) ;*/
4288
-
4289
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
4290
-		return 0/*addon.read16(adr)*/;
2729
+	if (adr >= 0x08000000 && adr < 0x0A010000)
2730
+		return 0;
4291 2731
 
4292
-    if ((adr>=0x04000400)&&(adr<0x04000520))
4293
-    {
4294
-        return SPU_ReadWord(adr);
4295
-    }
2732
+	if (adr >= 0x04000400 && adr < 0x04000520)
2733
+		return SPU_ReadWord(adr);
4296 2734
 
4297
-	if(adr>>24==4)
4298
-	{	//Address is an IO register
2735
+	if ((adr >> 24) == 4)
2736
+	{
2737
+		// Address is an IO register
4299 2738
 
4300
-		if(MMU_new.is_dma(adr)) return static_cast<uint16_t>(MMU_new.read_dma(ARMCPU_ARM7,16,adr));
2739
+		if (MMU_new.is_dma(adr))
2740
+			return static_cast<uint16_t>(MMU_new.read_dma(ARMCPU_ARM7, 16, adr));
4301 2741
 
4302
-		switch(adr)
2742
+		switch (adr)
4303 2743
 		{
4304
-			/*case REG_POWCNT2:
4305
-			{
4306
-				uint16_t ret = 0;
4307
-				ret |= nds.power2.speakers?BIT(0):0;
4308
-				ret |= nds.power2.wifi?BIT(1):0;
4309
-				return ret;
4310
-			}*/
4311
-
4312
-			//case REG_DISPx_VCOUNT: return nds.VCount;
4313
-			//case REG_RTC: return rtcRead();
4314
-			case REG_IME: return (uint16_t)MMU.reg_IME[ARMCPU_ARM7];
2744
+			case REG_IME:
2745
+				return static_cast<uint16_t>(MMU.reg_IME[ARMCPU_ARM7]);
4315 2746
 
4316 2747
 			case REG_IE:
4317
-				return (uint16_t)MMU.reg_IE[ARMCPU_ARM7];
2748
+				return static_cast<uint16_t>(MMU.reg_IE[ARMCPU_ARM7]);
4318 2749
 			case REG_IE + 2:
4319
-				return (uint16_t)(MMU.reg_IE[ARMCPU_ARM7]>>16);
4320
-
4321
-			case REG_IF: return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM7>());
4322
-			case REG_IF+2: return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM7>()>>16);
4323
-
4324
-			case REG_TM0CNTL :
4325
-			case REG_TM1CNTL :
4326
-			case REG_TM2CNTL :
4327
-			case REG_TM3CNTL :
4328
-				return read_timer(ARMCPU_ARM7,(adr&0xF)>>2);
2750
+				return static_cast<uint16_t>(MMU.reg_IE[ARMCPU_ARM7] >> 16);
4329 2751
 
4330
-			/*case REG_AUXSPICNT:
4331
-				return MMU.AUX_SPI_CNT;*/
2752
+			case REG_IF:
2753
+				return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM7>());
2754
+			case REG_IF + 2:
2755
+				return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM7>() >> 16);
4332 2756
 
4333
-			/*case REG_KEYINPUT:
4334
-				//here is an example of what not to do:
4335
-				//since the arm7 polls this (and EXTKEYIN) every frame, we shouldnt count this as an input check
4336
-				//LagFrameFlag=0;
4337
-				break;*/
2757
+			case REG_TM0CNTL:
2758
+			case REG_TM1CNTL:
2759
+			case REG_TM2CNTL:
2760
+			case REG_TM3CNTL:
2761
+				return read_timer(ARMCPU_ARM7, (adr & 0xF) >> 2);
4338 2762
 
4339
-			/*case REG_EXTKEYIN:
4340
-				{
4341
-					//this is gross. we should generate this whole reg instead of poking it in ndssystem
4342
-					uint16_t ret = MMU.ARM7_REG[0x136];
4343
-					if(nds.isTouch) ret &= ~64;
4344
-					else ret |= 64;
4345
-					return ret;
4346
-				}*/
2763
+			case REG_VRAMSTAT:
2764
+				// make sure WRAMSTAT is stashed and then fallthrough to return the value from memory. i know, gross.
2765
+				T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, MMU.WRAMCNT);
2766
+				break;
4347 2767
 		}
4348
-		return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]);
2768
+		return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]);
4349 2769
 	}
4350 2770
 
4351
-	//bool unmapped = false/*, restricted*/;
4352
-	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4353
-	//if(unmapped) return 0;
4354
-
4355 2771
 	/* Returns data from memory */
4356 2772
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF
4357 2773
 	return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]);
4358 2774
 }
4359
-//================================================= MMU ARM7 read 32
2775
+
2776
+// ================================================= MMU ARM7 read 32
4360 2777
 uint32_t FASTCALL _MMU_ARM7_read32(uint32_t adr)
4361 2778
 {
4362 2779
 	adr &= 0x0FFFFFFC;
4363 2780
 
4364
-	//mmu_log_debug_ARM7(adr, "(read32) 0x%08X", T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][(adr>>20)&0xFF], adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr>>20)&0xFF]));
4365
-
4366 2781
 	if (adr < 0x4000)
4367 2782
 	{
4368
-		//uint32_t prot = T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x04000308 & MMU.MMU_MASK[ARMCPU_ARM7][0x40]);
4369
-		//if (prot) INFO("MMU7 read 32 at 0x%08X (PC 0x%08X) BIOSPROT address 0x%08X\n", adr, NDS_ARM7.R[15], prot);
4370
-		if (NDS_ARM7.R[15] > 0x3FFF)
2783
+		if (NDS_ARM7.instruct_adr > 0x3FFF)
4371 2784
 			return 0xFFFFFFFF;
4372 2785
 	}
4373 2786
 
4374
-	//wifi mac access
4375
-	/*if ((adr & 0xFFFF0000) == 0x04800000)
4376
-		return WIFI_read16(adr) | (WIFI_read16(adr+2) << 16);*/
4377
-
4378
-	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
4379
-		return 0/*addon.read32(adr)*/;
2787
+	if (adr >= 0x08000000 && adr < 0x0A010000)
2788
+		return 0;
4380 2789
 
4381
-    if ((adr>=0x04000400)&&(adr<0x04000520))
4382
-    {
4383
-        return SPU_ReadLong(adr);
4384
-    }
2790
+	if (adr >= 0x04000400 && adr < 0x04000520)
2791
+		return SPU_ReadLong(adr);
4385 2792
 
4386
-	if((adr >> 24) == 4)
4387
-	{	//Address is an IO register
2793
+	if ((adr >> 24) == 4)
2794
+	{
2795
+		// Address is an IO register
4388 2796
 
4389
-		if(MMU_new.is_dma(adr)) return MMU_new.read_dma(ARMCPU_ARM7,32,adr);
2797
+		if (MMU_new.is_dma(adr))
2798
+			return MMU_new.read_dma(ARMCPU_ARM7, 32, adr);
4390 2799
 
4391
-		switch(adr)
2800
+		switch (adr)
4392 2801
 		{
4393
-			//case REG_RTC: return (uint32_t)rtcRead();
4394
-			//case REG_DISPx_VCOUNT: return nds.VCount;
4395
-
4396
-			case REG_IME :
2802
+			case REG_IME:
4397 2803
 				return MMU.reg_IME[ARMCPU_ARM7];
4398
-			case REG_IE :
2804
+			case REG_IE:
4399 2805
 				return MMU.reg_IE[ARMCPU_ARM7];
4400
-			case REG_IF: return MMU.gen_IF<ARMCPU_ARM7>();
4401
-			case REG_IPCFIFORECV :
2806
+			case REG_IF:
2807
+				return MMU.gen_IF<ARMCPU_ARM7>();
2808
+			case REG_IPCFIFORECV:
4402 2809
 				return IPC_FIFOrecv(ARMCPU_ARM7);
4403
-            case REG_TM0CNTL :
4404
-            case REG_TM1CNTL :
4405
-            case REG_TM2CNTL :
4406
-            case REG_TM3CNTL :
2810
+			case REG_TM0CNTL:
2811
+			case REG_TM1CNTL:
2812
+			case REG_TM2CNTL:
2813
+			case REG_TM3CNTL:
4407 2814
 			{
4408 2815
 				uint32_t val = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], (adr + 2) & 0xFFF);
4409
-				return MMU.timer[ARMCPU_ARM7][(adr&0xF)>>2] | (val<<16);
2816
+				return MMU.timer[ARMCPU_ARM7][(adr & 0xF) >> 2] | (val << 16);
4410 2817
 			}
4411 2818
 			case REG_GCROMCTRL:
4412
-			{
4413
-				//INFO("arm7 romctrl read\n");
4414 2819
 				break;
4415
-			}
4416
-            case REG_GCDATAIN:
2820
+			case REG_GCDATAIN:
4417 2821
 				return MMU_readFromGC<ARMCPU_ARM7>();
4418 2822
 
2823
+			case REG_VRAMSTAT:
2824
+				// make sure WRAMSTAT is stashed and then fallthrough return the value from memory. i know, gross.
2825
+				T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, MMU.WRAMCNT);
2826
+				break;
4419 2827
 		}
4420
-		return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]);
4421
-	}
4422 2828
 
4423
-	//bool unmapped = false/*, restricted*/;
4424
-	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4425
-	//if(unmapped) return 0;
2829
+		return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]);
2830
+	}
4426 2831
 
4427
-	//Returns data from memory
2832
+	// Returns data from memory
4428 2833
 	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [zeromus, inspired by shash]
4429 2834
 	return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]);
4430 2835
 }
4431 2836
 
4432
-//=========================================================================================================
4433
-
4434
-/*uint32_t FASTCALL MMU_read32(uint32_t proc, uint32_t adr)
4435
-{
4436
-	ASSERT_UNALIGNED((adr&3)==0);
4437
-
4438
-	if(proc==0)
4439
-		return _MMU_ARM9_read32(adr);
4440
-	else
4441
-		return _MMU_ARM7_read32(adr);
4442
-}*/
4443
-
4444
-/*uint16_t FASTCALL MMU_read16(uint32_t proc, uint32_t adr)
4445
-{
4446
-	ASSERT_UNALIGNED((adr&1)==0);
4447
-
4448
-	if(proc==0)
4449
-		return _MMU_ARM9_read16(adr);
4450
-	else
4451
-		return _MMU_ARM7_read16(adr);
4452
-}*/
4453
-
4454
-/*uint8_t FASTCALL MMU_read8(uint32_t proc, uint32_t adr)
4455
-{
4456
-	if(proc==0)
4457
-		return _MMU_ARM9_read08(adr);
4458
-	else
4459
-		return _MMU_ARM7_read08(adr);
4460
-}*/
4461
-
4462
-/*void FASTCALL MMU_write32(uint32_t proc, uint32_t adr, uint32_t val)
4463
-{
4464
-	ASSERT_UNALIGNED((adr&3)==0);
4465
-
4466
-	if(proc==0)
4467
-		_MMU_ARM9_write32(adr, val);
4468
-	else
4469
-		_MMU_ARM7_write32(adr,val);
4470
-}*/
4471
-
4472
-/*void FASTCALL MMU_write16(uint32_t proc, uint32_t adr, uint16_t val)
4473
-{
4474
-	ASSERT_UNALIGNED((adr&1)==0);
4475
-
4476
-	if(proc==0)
4477
-		_MMU_ARM9_write16(adr, val);
4478
-	else
4479
-		_MMU_ARM7_write16(adr,val);
4480
-}*/
4481
-
4482
-/*void FASTCALL MMU_write8(uint32_t proc, uint32_t adr, uint8_t val)
4483
-{
4484
-	if(proc==0)
4485
-		_MMU_ARM9_write08(adr, val);
4486
-	else
4487
-		_MMU_ARM7_write08(adr,val);
4488
-}*/
4489
-
4490
-/*void FASTCALL MMU_DumpMemBlock(uint8_t proc, uint32_t address, uint32_t size, uint8_t *buffer)
4491
-{
4492
-	uint32_t i;
4493
-	uint32_t curaddr;
4494
-
4495
-	for(i = 0, curaddr = address; i < size; i++, curaddr++)
4496
-	{
4497
-		buffer[i] = _MMU_read08(proc,MMU_AT_DEBUG,curaddr);
4498
-	}
4499
-}*/
4500
-
2837
+// =========================================================================================================
4501 2838
 
4502
-//these templates needed to be instantiated manually
2839
+// these templates needed to be instantiated manually
4503 2840
 template uint32_t MMU_struct::gen_IF<ARMCPU_ARM9>();
4504 2841
 template uint32_t MMU_struct::gen_IF<ARMCPU_ARM7>();
4505
-
4506
-////////////////////////////////////////////////////////////
4507
-//function pointer handlers for gdb stub stuff
4508
-
4509
-/*static uint16_t FASTCALL arm9_prefetch16( void *, uint32_t adr) {
4510
-	return _MMU_read16<ARMCPU_ARM9,MMU_AT_CODE>(adr);
4511
-}
4512
-
4513
-static uint32_t FASTCALL arm9_prefetch32( void *, uint32_t adr) {
4514
-	return _MMU_read32<ARMCPU_ARM9,MMU_AT_CODE>(adr);
4515
-}
4516
-
4517
-static uint8_t FASTCALL arm9_read8( void *, uint32_t adr) {
4518
-	return _MMU_read08<ARMCPU_ARM9>(adr);
4519
-}
4520
-
4521
-static uint16_t FASTCALL arm9_read16( void *, uint32_t adr) {
4522
-	return _MMU_read16<ARMCPU_ARM9>(adr);
4523
-}
4524
-
4525
-static uint32_t FASTCALL arm9_read32( void *, uint32_t adr) {
4526
-	return _MMU_read32<ARMCPU_ARM9>(adr);
4527
-}
4528
-
4529
-static void FASTCALL arm9_write8(void *, uint32_t adr, uint8_t val) {
4530
-	_MMU_write08<ARMCPU_ARM9>(adr, val);
4531
-}
4532
-
4533
-static void FASTCALL arm9_write16(void *, uint32_t adr, uint16_t val) {
4534
-	_MMU_write16<ARMCPU_ARM9>(adr, val);
4535
-}
4536
-
4537
-static void FASTCALL arm9_write32(void *, uint32_t adr, uint32_t val) {
4538
-	_MMU_write32<ARMCPU_ARM9>(adr, val);
4539
-}
4540
-
4541
-static uint16_t FASTCALL arm7_prefetch16( void *, uint32_t adr) {
4542
-  return _MMU_read16<ARMCPU_ARM7,MMU_AT_CODE>(adr);
4543
-}
4544
-
4545
-static uint32_t FASTCALL arm7_prefetch32( void *, uint32_t adr) {
4546
-  return _MMU_read32<ARMCPU_ARM7,MMU_AT_CODE>(adr);
4547
-}
4548
-
4549
-static uint8_t FASTCALL arm7_read8( void *, uint32_t adr) {
4550
-  return _MMU_read08<ARMCPU_ARM7>(adr);
4551
-}
4552
-
4553
-static uint16_t FASTCALL arm7_read16( void *, uint32_t adr) {
4554
-  return _MMU_read16<ARMCPU_ARM7>(adr);
4555
-}
4556
-
4557
-static uint32_t FASTCALL arm7_read32( void *, uint32_t adr) {
4558
-  return _MMU_read32<ARMCPU_ARM7>(adr);
4559
-}
4560
-
4561
-static void FASTCALL arm7_write8(void *, uint32_t adr, uint8_t val) {
4562
-  _MMU_write08<ARMCPU_ARM7>(adr, val);
4563
-}
4564
-
4565
-static void FASTCALL arm7_write16(void *, uint32_t adr, uint16_t val) {
4566
-  _MMU_write16<ARMCPU_ARM7>(adr, val);
4567
-}
4568
-
4569
-static void FASTCALL arm7_write32(void *, uint32_t adr, uint32_t val) {
4570
-  _MMU_write32<ARMCPU_ARM7>(adr, val);
4571
-}*/
4572
-
4573
-
4574
-
4575
-/*
4576
- * the base memory interfaces
4577
- */
4578
-/*struct armcpu_memory_iface arm9_base_memory_iface = {
4579
-  arm9_prefetch32,
4580
-  arm9_prefetch16,
4581
-
4582
-  arm9_read8,
4583
-  arm9_read16,
4584
-  arm9_read32,
4585
-
4586
-  arm9_write8,
4587
-  arm9_write16,
4588
-  arm9_write32
4589
-};
4590
-
4591
-struct armcpu_memory_iface arm7_base_memory_iface = {
4592
-  arm7_prefetch32,
4593
-  arm7_prefetch16,
4594
-
4595
-  arm7_read8,
4596
-  arm7_read16,
4597
-  arm7_read32,
4598
-
4599
-  arm7_write8,
4600
-  arm7_write16,
4601
-  arm7_write32
4602
-};*/
4603
-
4604
-/*
4605
- * The direct memory interface for the ARM9.
4606
- * This avoids the ARM9 protection unit when accessing
4607
- * memory.
4608
- */
4609
-/*struct armcpu_memory_iface arm9_direct_memory_iface = {
4610
-  NULL,
4611
-  NULL,
4612
-
4613
-  arm9_read8,
4614
-  arm9_read16,
4615
-  arm9_read32,
4616
-
4617
-  arm9_write8,
4618
-  arm9_write16,
4619
-  arm9_write32
4620
-};*/
4621
-
4622
-
4623
-/////////////////////////////////////////////////////////////////
4624
-/////////////////////////////////////////////////////////////////
4625
-/////////////////////////////////////////////////////////////////
4626
-/////////////////////////////////////////////////////////////////
4627
-/////////////////////////////////////////////////////////////////
4628
-/////////////////////////////////////////////////////////////////
4629
-
4630
-//#ifdef PROFILE_MEMORY_ACCESS
4631
-//
4632
-//#define PROFILE_PREFETCH 0
4633
-//#define PROFILE_READ 1
4634
-//#define PROFILE_WRITE 2
4635
-//
4636
-//struct mem_access_profile {
4637
-//  uint64_t num_accesses;
4638
-//  uint32_t address_mask;
4639
-//  uint32_t masked_value;
4640
-//};
4641
-//
4642
-//#define PROFILE_NUM_MEM_ACCESS_PROFILES 4
4643
-//
4644
-//static uint64_t profile_num_accesses[2][3];
4645
-//static uint64_t profile_unknown_addresses[2][3];
4646
-//static struct mem_access_profile
4647
-//profile_memory_accesses[2][3][PROFILE_NUM_MEM_ACCESS_PROFILES];
4648
-//
4649
-//static void
4650
-//setup_profiling() {
4651
-//  int i;
4652
-//
4653
-//  for ( i = 0; i < 2; i++) {
4654
-//    int access_type;
4655
-//
4656
-//    for ( access_type = 0; access_type < 3; access_type++) {
4657
-//      profile_num_accesses[i][access_type] = 0;
4658
-//      profile_unknown_addresses[i][access_type] = 0;
4659
-//
4660
-//      /*
4661
-//       * Setup the access testing structures
4662
-//       */
4663
-//      profile_memory_accesses[i][access_type][0].address_mask = 0x0e000000;
4664
-//      profile_memory_accesses[i][access_type][0].masked_value = 0x00000000;
4665
-//      profile_memory_accesses[i][access_type][0].num_accesses = 0;
4666
-//
4667
-//      /* main memory */
4668
-//      profile_memory_accesses[i][access_type][1].address_mask = 0x0f000000;
4669
-//      profile_memory_accesses[i][access_type][1].masked_value = 0x02000000;
4670
-//      profile_memory_accesses[i][access_type][1].num_accesses = 0;
4671
-//
4672
-//      /* shared memory */
4673
-//      profile_memory_accesses[i][access_type][2].address_mask = 0x0f800000;
4674
-//      profile_memory_accesses[i][access_type][2].masked_value = 0x03000000;
4675
-//      profile_memory_accesses[i][access_type][2].num_accesses = 0;
4676
-//
4677
-//      /* arm7 memory */
4678
-//      profile_memory_accesses[i][access_type][3].address_mask = 0x0f800000;
4679
-//      profile_memory_accesses[i][access_type][3].masked_value = 0x03800000;
4680
-//      profile_memory_accesses[i][access_type][3].num_accesses = 0;
4681
-//    }
4682
-//  }
4683
-//}
4684
-//
4685
-//static void
4686
-//profile_memory_access( int arm9, uint32_t adr, int access_type) {
4687
-//  static int first = 1;
4688
-//  int mem_profile;
4689
-//  int address_found = 0;
4690
-//
4691
-//  if ( first) {
4692
-//    setup_profiling();
4693
-//    first = 0;
4694
-//  }
4695
-//
4696
-//  profile_num_accesses[arm9][access_type] += 1;
4697
-//
4698
-//  for ( mem_profile = 0;
4699
-//        mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES &&
4700
-//          !address_found;
4701
-//        mem_profile++) {
4702
-//    if ( (adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask) ==
4703
-//         profile_memory_accesses[arm9][access_type][mem_profile].masked_value) {
4704
-//      /*printf( "adr %08x mask %08x res %08x expected %08x\n",
4705
-//              adr,
4706
-//              profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
4707
-//              adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
4708
-//              profile_memory_accesses[arm9][access_type][mem_profile].masked_value);*/
4709
-//      address_found = 1;
4710
-//      profile_memory_accesses[arm9][access_type][mem_profile].num_accesses += 1;
4711
-//    }
4712
-//  }
4713
-//
4714
-//  if ( !address_found) {
4715
-//    profile_unknown_addresses[arm9][access_type] += 1;
4716
-//  }
4717
-//}
4718
-//
4719
-//
4720
-//static const char *access_type_strings[] = {
4721
-//  "prefetch",
4722
-//  "read    ",
4723
-//  "write   "
4724
-//};
4725
-//
4726
-//void
4727
-//print_memory_profiling() {
4728
-//  int arm;
4729
-//
4730
-//  printf("------ Memory access profile ------\n");
4731
-//
4732
-//  for ( arm = 0; arm < 2; arm++) {
4733
-//    int access_type;
4734
-//
4735
-//    for ( access_type = 0; access_type < 3; access_type++) {
4736
-//      int mem_profile;
4737
-//      printf("ARM%c: num of %s %lld\n",
4738
-//             arm ? '9' : '7',
4739
-//             access_type_strings[access_type],
4740
-//             profile_num_accesses[arm][access_type]);
4741
-//
4742
-//      for ( mem_profile = 0;
4743
-//            mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES;
4744
-//            mem_profile++) {
4745
-//        printf( "address %08x: %lld\n",
4746
-//                profile_memory_accesses[arm][access_type][mem_profile].masked_value,
4747
-//                profile_memory_accesses[arm][access_type][mem_profile].num_accesses);
4748
-//      }
4749
-//
4750
-//      printf( "unknown addresses %lld\n",
4751
-//              profile_unknown_addresses[arm][access_type]);
4752
-//
4753
-//      printf( "\n");
4754
-//    }
4755
-//  }
4756
-//
4757
-//  printf("------ End of Memory access profile ------\n\n");
4758
-//}
4759
-//#else
4760
-//void
4761
-//print_memory_profiling() {
4762
-//}
4763
-//#endif /* End of PROFILE_MEMORY_ACCESS area */
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
... ...
@@ -1985,7 +1985,7 @@ void DmaController::doCopy()
1985 1985
 	//determine how we're going to copy
1986 1986
 	bool bogarted = false;
1987 1987
 	uint32_t sz = (bitWidth==EDMABitWidth_16)?2:4;
1988
-	uint32_t dstinc = 0,srcinc;
1988
+	uint32_t dstinc = 0,srcinc = 0;
1989 1989
 	switch(dar) {
1990 1990
 		case EDMADestinationUpdate_Increment       :  dstinc =  sz; break;
1991 1991
 		case EDMADestinationUpdate_Decrement       :  dstinc = (uint32_t)-(int32_t)sz; break;
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,4763 @@
1
+/*
2
+	Copyright (C) 2006 yopyop
3
+	Copyright (C) 2007 shash
4
+	Copyright (C) 2007-2012 DeSmuME team
5
+
6
+	This file is free software: you can redistribute it and/or modify
7
+	it under the terms of the GNU General Public License as published by
8
+	the Free Software Foundation, either version 2 of the License, or
9
+	(at your option) any later version.
10
+
11
+	This file is distributed in the hope that it will be useful,
12
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+	GNU General Public License for more details.
15
+
16
+	You should have received a copy of the GNU General Public License
17
+	along with the this software.  If not, see <http://www.gnu.org/licenses/>.
18
+*/
19
+
20
+#include <sstream>
21
+#include <cstdlib>
22
+#include <cmath>
23
+#include <cstring>
24
+#include <cassert>
25
+
26
+#include "common.h"
27
+//#include "debug.h"
28
+#include "NDSSystem.h"
29
+#include "cp15.h"
30
+//#include "wifi.h"
31
+#include "registers.h"
32
+//#include "render3D.h"
33
+//#include "gfx3d.h"
34
+//#include "rtc.h"
35
+#include "mc.h"
36
+//#include "addons.h"
37
+#include "slot1.h"
38
+//#include "mic.h"
39
+//#include "movie.h"
40
+#include "readwrite.h"
41
+#include "MMU_timing.h"
42
+
43
+//#undef min
44
+
45
+/*#ifdef DO_ASSERT_UNALIGNED
46
+#define ASSERT_UNALIGNED(x) assert(x)
47
+#else
48
+#define ASSERT_UNALIGNED(x)
49
+#endif*/
50
+
51
+//http://home.utah.edu/~nahaj/factoring/isqrt.c.html
52
+static uint64_t isqrt (uint64_t x) {
53
+  uint64_t   squaredbit, remainder, root;
54
+
55
+   if (x<1) return 0;
56
+
57
+   /* Load the binary constant 01 00 00 ... 00, where the number
58
+    * of zero bits to the right of the single one bit
59
+    * is even, and the one bit is as far left as is consistant
60
+    * with that condition.)
61
+    */
62
+   squaredbit  = (uint64_t) ((((uint64_t) ~0LL) >> 1) &
63
+                        ~(((uint64_t) ~0LL) >> 2));
64
+   /* This portable load replaces the loop that used to be
65
+    * here, and was donated by  legalize@xmission.com
66
+    */
67
+
68
+   /* Form bits of the answer. */
69
+   remainder = x;  root = 0;
70
+   while (squaredbit > 0) {
71
+     if (remainder >= (squaredbit | root)) {
72
+         remainder -= (squaredbit | root);
73
+         root >>= 1; root |= squaredbit;
74
+     } else {
75
+         root >>= 1;
76
+     }
77
+     squaredbit >>= 2;
78
+   }
79
+
80
+   return root;
81
+}
82
+
83
+uint32_t partie = 1;
84
+uint32_t _MMU_MAIN_MEM_MASK = 0x3FFFFF;
85
+uint32_t _MMU_MAIN_MEM_MASK16 = 0x3FFFFF & ~1;
86
+uint32_t _MMU_MAIN_MEM_MASK32 = 0x3FFFFF & ~3;
87
+
88
+//#define	_MMU_DEBUG
89
+
90
+/*#ifdef _MMU_DEBUG
91
+
92
+#include <stdarg.h>
93
+void mmu_log_debug_ARM9(uint32_t adr, const char *fmt, ...)
94
+{
95
+	if (adr < 0x4000000) return;
96
+//	if (adr > 0x4100014) return;
97
+//#if 1
98
+	if (adr >= 0x4000000 && adr <= 0x400006E) return;		// Display Engine A
99
+	if (adr >= 0x40000B0 && adr <= 0x4000134) return;		// DMA, Timers and Keypad
100
+	if (adr >= 0x4000180 && adr <= 0x40001BC) return;		// IPC/ROM
101
+	if (adr >= 0x4000204 && adr <= 0x400024A) return;		// Memory & IRQ control
102
+	if (adr >= 0x4000280 && adr <= 0x4000306) return;		// Maths
103
+	if (adr >= 0x4000320 && adr <= 0x40006A3) return;		// 3D dispaly engine
104
+	if (adr >= 0x4001000 && adr <= 0x400106E) return;		// Display Engine B
105
+	if (adr >= 0x4100000 && adr <= 0x4100014) return;		// IPC/ROM
106
+//#endif
107
+	va_list list;
108
+	char msg[512];
109
+
110
+	memset(msg,0,512);
111
+
112
+	va_start(list,fmt);
113
+		_vsnprintf(msg,511,fmt,list);
114
+	va_end(list);
115
+
116
+	INFO("MMU ARM9 0x%08X: %s\n", adr, msg);
117
+}
118
+
119
+void mmu_log_debug_ARM7(uint32_t adr, const char *fmt, ...)
120
+{
121
+	if (adr < 0x4000004) return;
122
+	if (adr > 0x4808FFF) return;
123
+#if 1
124
+	if (adr >= 0x4000004 && adr < 0x4000180) return;		// ARM7 I/O Map
125
+	if (adr >= 0x4000180 && adr <= 0x40001C4) return;		// IPC/ROM
126
+	if (adr >= 0x4000204 && adr <= 0x400030C) return;		// Memory and IRQ Control
127
+	if (adr >= 0x4000400 && adr <= 0x400051E) return;		// Sound Registers
128
+	if (adr >= 0x4100000 && adr <= 0x4100014) return;		// IPC/ROM
129
+	if (adr >= 0x4800000 && adr <= 0x4808FFF) return;		// WLAN Registers
130
+#endif
131
+	va_list list;
132
+	char msg[512];
133
+
134
+	memset(msg,0,512);
135
+
136
+	va_start(list,fmt);
137
+		_vsnprintf(msg,511,fmt,list);
138
+	va_end(list);
139
+
140
+	INFO("MMU ARM7 0x%08X: %s\n", adr, msg);
141
+
142
+}
143
+#else
144
+#define mmu_log_debug_ARM9(...)
145
+#define mmu_log_debug_ARM7(...)
146
+#endif*/
147
+
148
+
149
+//#define LOG_CARD
150
+//#define LOG_GPU
151
+//#define LOG_DMA
152
+//#define LOG_DMA2
153
+//#define LOG_DIV
154
+
155
+#define DUP2(x)  x, x
156
+#define DUP4(x)  x, x, x, x
157
+#define DUP8(x)  x, x, x, x,  x, x, x, x
158
+#define DUP16(x) x, x, x, x,  x, x, x, x,  x, x, x, x,  x, x, x, x
159
+
160
+MMU_struct MMU;
161
+MMU_struct_new MMU_new;
162
+MMU_struct_timing MMU_timing;
163
+
164
+uint8_t * MMU_struct::MMU_MEM[2][256] = {
165
+	//arm9
166
+	{
167
+		/* 0X*/	DUP16(MMU.ARM9_ITCM),
168
+		/* 1X*/	//DUP16(MMU.ARM9_ITCM)
169
+		/* 1X*/	DUP16(MMU.UNUSED_RAM),
170
+		/* 2X*/	DUP16(MMU.MAIN_MEM),
171
+		/* 3X*/	DUP16(MMU.SWIRAM),
172
+		/* 4X*/	DUP16(MMU.ARM9_REG),
173
+		/* 5X*/	DUP16(MMU.ARM9_VMEM),
174
+		/* 6X*/	DUP16(MMU.ARM9_LCD),
175
+		/* 7X*/	DUP16(MMU.ARM9_OAM),
176
+		/* 8X*/	DUP16(NULL),
177
+		/* 9X*/	DUP16(NULL),
178
+		/* AX*/	DUP16(MMU.UNUSED_RAM),
179
+		/* BX*/	DUP16(MMU.UNUSED_RAM),
180
+		/* CX*/	DUP16(MMU.UNUSED_RAM),
181
+		/* DX*/	DUP16(MMU.UNUSED_RAM),
182
+		/* EX*/	DUP16(MMU.UNUSED_RAM),
183
+		/* FX*/	DUP16(MMU.ARM9_BIOS)
184
+	},
185
+	//arm7
186
+	{
187
+		/* 0X*/	DUP16(MMU.ARM7_BIOS),
188
+		/* 1X*/	DUP16(MMU.UNUSED_RAM),
189
+		/* 2X*/	DUP16(MMU.MAIN_MEM),
190
+		/* 3X*/	DUP8(MMU.SWIRAM),
191
+				DUP8(MMU.ARM7_ERAM),
192
+		/* 4X*/	DUP8(MMU.ARM7_REG),
193
+				DUP8(MMU.ARM7_WIRAM),
194
+		/* 5X*/	DUP16(MMU.UNUSED_RAM),
195
+		/* 6X*/	DUP16(MMU.ARM9_LCD),
196
+		/* 7X*/	DUP16(MMU.UNUSED_RAM),
197
+		/* 8X*/	DUP16(NULL),
198
+		/* 9X*/	DUP16(NULL),
199
+		/* AX*/	DUP16(MMU.UNUSED_RAM),
200
+		/* BX*/	DUP16(MMU.UNUSED_RAM),
201
+		/* CX*/	DUP16(MMU.UNUSED_RAM),
202
+		/* DX*/	DUP16(MMU.UNUSED_RAM),
203
+		/* EX*/	DUP16(MMU.UNUSED_RAM),
204
+		/* FX*/	DUP16(MMU.UNUSED_RAM)
205
+		}
206
+};
207
+
208
+uint32_t MMU_struct::MMU_MASK[2][256] = {
209
+	//arm9
210
+	{
211
+		/* 0X*/	DUP16(0x00007FFF),
212
+		/* 1X*/	//DUP16(0x00007FFF)
213
+		/* 1X*/	DUP16(0x00000003),
214
+		/* 2X*/	DUP16(0x003FFFFF),
215
+		/* 3X*/	DUP16(0x00007FFF),
216
+		/* 4X*/	DUP16(0x00FFFFFF),
217
+		/* 5X*/	DUP16(0x000007FF),
218
+		/* 6X*/	DUP16(0x00FFFFFF),
219
+		/* 7X*/	DUP16(0x000007FF),
220
+		/* 8X*/	DUP16(0x00000003),
221
+		/* 9X*/	DUP16(0x00000003),
222
+		/* AX*/	DUP16(0x00000003),
223
+		/* BX*/	DUP16(0x00000003),
224
+		/* CX*/	DUP16(0x00000003),
225
+		/* DX*/	DUP16(0x00000003),
226
+		/* EX*/	DUP16(0x00000003),
227
+		/* FX*/	DUP16(0x00007FFF)
228
+	},
229
+	//arm7
230
+	{
231
+		/* 0X*/	DUP16(0x00003FFF),
232
+		/* 1X*/	DUP16(0x00000003),
233
+		/* 2X*/	DUP16(0x003FFFFF),
234
+		/* 3X*/	DUP8(0x00007FFF),
235
+				DUP8(0x0000FFFF),
236
+		/* 4X*/	DUP8(0x00FFFFFF),
237
+				DUP8(0x0000FFFF),
238
+		/* 5X*/	DUP16(0x00000003),
239
+		/* 6X*/	DUP16(0x00FFFFFF),
240
+		/* 7X*/	DUP16(0x00000003),
241
+		/* 8X*/	DUP16(0x00000003),
242
+		/* 9X*/	DUP16(0x00000003),
243
+		/* AX*/	DUP16(0x00000003),
244
+		/* BX*/	DUP16(0x00000003),
245
+		/* CX*/	DUP16(0x00000003),
246
+		/* DX*/	DUP16(0x00000003),
247
+		/* EX*/	DUP16(0x00000003),
248
+		/* FX*/	DUP16(0x00000003)
249
+		}
250
+};
251
+
252
+// this logic was moved to MMU_timing.h
253
+//CACHE_ALIGN
254
+//TWaitState MMU_struct::MMU_WAIT16[2][16] = {
255
+//	{ 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1 }, //arm9
256
+//	{ 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1 }, //arm7
257
+//};
258
+//
259
+//CACHE_ALIGN
260
+//TWaitState MMU_struct::MMU_WAIT32[2][16] = {
261
+//	{ 1, 1, 1, 1, 1, 2, 2, 1, 8, 8, 5, 1, 1, 1, 1, 1 }, //arm9
262
+//	{ 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 5, 1, 1, 1, 1, 1 }, //arm7
263
+//};
264
+
265
+//////////////////////////////////////////////////////////////
266
+
267
+//-------------
268
+//VRAM MEMORY MAPPING
269
+//-------------
270
+//(Everything is mapped through to ARM9_LCD in blocks of 16KB)
271
+
272
+//for all of the below, values = 41 indicate unmapped memory
273
+static const uint8_t VRAM_PAGE_UNMAPPED = 41;
274
+
275
+static const unsigned VRAM_LCDC_PAGES = 41;
276
+uint8_t vram_lcdc_map[VRAM_LCDC_PAGES];
277
+
278
+//in the range of 0x06000000 - 0x06800000 in 16KB pages (the ARM9 vram mappable area)
279
+//this maps to 16KB pages in the LCDC buffer which is what will actually contain the data
280
+uint8_t vram_arm9_map[VRAM_ARM9_PAGES];
281
+
282
+//this chooses which banks are mapped in the 128K banks starting at 0x06000000 in ARM7
283
+uint8_t vram_arm7_map[2];
284
+
285
+//----->
286
+//consider these later, for better recordkeeping, instead of using the uint8_t* in MMU
287
+
288
+////for each 128KB texture slot, this maps to a 16KB starting page in the LCDC buffer
289
+//#define VRAM_TEX_SLOTS 4
290
+//uint8_t vram_tex_map[VRAM_TEX_SLOTS];
291
+//
292
+////for each 16KB tex palette slot, this maps to a 16KB starting page in the LCDC buffer
293
+//#define VRAM_TEX_PALETTE_SLOTS 6
294
+//uint8_t vram_tex_palette_map[VRAM_TEX_PALETTE_SLOTS];
295
+
296
+//<---------
297
+
298
+
299
+//void MMU_VRAM_unmap_all();
300
+
301
+struct TVramBankInfo {
302
+	uint8_t page_addr, num_pages;
303
+};
304
+
305
+static const TVramBankInfo vram_bank_info[VRAM_BANKS] = {
306
+	{0,8},
307
+	{8,8},
308
+	{16,8},
309
+	{24,8},
310
+	{32,4},
311
+	{36,1},
312
+	{37,1},
313
+	{38,2},
314
+	{40,1}
315
+};
316
+
317
+//this is to remind you that the LCDC mapping returns a strange value (not 0x06800000) as you would expect
318
+//in order to play nicely with the MMU address and mask tables
319
+static const uint32_t LCDC_HACKY_LOCATION = 0x06000000;
320
+
321
+//maps an ARM9 BG/OBJ or LCDC address into an LCDC address, and informs the caller of whether it isn't mapped
322
+//TODO - in cases where this does some mapping work, we could bypass the logic at the end of the _read* and _write* routines
323
+//this is a good optimization to consider
324
+//template<int PROCNUM>
325
+static inline uint32_t MMU_LCDmap(uint32_t addr, bool& unmapped, bool& restricted)
326
+{
327
+	unmapped = false;
328
+	restricted = false; //this will track whether 8bit writes are allowed
329
+
330
+	//in case the address is entirely outside of the interesting ranges
331
+	if(addr < 0x06000000) return addr;
332
+	if(addr >= 0x07000000) return addr;
333
+
334
+	//shared wram mapping for arm7
335
+	/*if(PROCNUM==ARMCPU_ARM7)
336
+	{
337
+		//necessary? not sure
338
+		//addr &= 0x3FFFF;
339
+		//addr += 0x06000000;
340
+		uint32_t ofs = addr & 0x1FFFF;
341
+		uint32_t bank = (addr >> 17)&1;
342
+		if(vram_arm7_map[bank] == VRAM_PAGE_UNMAPPED)
343
+		{
344
+			unmapped = true;
345
+			return 0;
346
+		}
347
+		return LCDC_HACKY_LOCATION + (vram_arm7_map[bank]<<14) + ofs;
348
+	}*/
349
+
350
+	restricted = true;
351
+
352
+	//handle LCD memory mirroring
353
+	if(addr>=0x068A4000)
354
+		addr = 0x06800000 +
355
+		//(addr%0xA4000); //yuck!! is this even how it mirrors? but we have to keep from overrunning the buffer somehow
356
+		(addr&0x80000); //just as likely to be right (I have no clue how it should work) but faster.
357
+
358
+	uint32_t vram_page;
359
+	uint32_t ofs = addr & 0x3FFF;
360
+
361
+	//return addresses in LCDC range
362
+	if(addr>=0x06800000)
363
+	{
364
+		//already in LCDC range. just look it up to see whether it is unmapped
365
+		vram_page = (addr>>14)&63;
366
+		assert(vram_page<VRAM_LCDC_PAGES);
367
+		vram_page = vram_lcdc_map[vram_page];
368
+	}
369
+	else
370
+	{
371
+		//map addresses in BG/OBJ range to an LCDC range
372
+		vram_page = (addr>>14)&(VRAM_ARM9_PAGES-1);
373
+		assert(vram_page<VRAM_ARM9_PAGES);
374
+		vram_page = vram_arm9_map[vram_page];
375
+	}
376
+
377
+	if(vram_page == VRAM_PAGE_UNMAPPED)
378
+	{
379
+		unmapped = true;
380
+		return 0;
381
+	}
382
+	else
383
+		return LCDC_HACKY_LOCATION + (vram_page<<14) + ofs;
384
+}
385
+
386
+
387
+//#define LOG_VRAM_ERROR() LOG("No data for block %i MST %i\n", block, VRAMBankCnt & 0x07);
388
+
389
+VramConfiguration vramConfiguration;
390
+
391
+/*std::string VramConfiguration::describePurpose(Purpose p) {
392
+	switch(p) {
393
+		case OFF: return "OFF";
394
+		case INVALID: return "INVALID";
395
+		case ABG: return "ABG";
396
+		case BBG: return "BBG";
397
+		case AOBJ: return "AOBJ";
398
+		case BOBJ: return "BOBJ";
399
+		case LCDC: return "LCDC";
400
+		case ARM7: return "ARM7";
401
+		case TEX: return "TEX";
402
+		case TEXPAL: return "TEXPAL";
403
+		case ABGEXTPAL: return "ABGEXTPAL";
404
+		case BBGEXTPAL: return "BBGEXTPAL";
405
+		case AOBJEXTPAL: return "AOBJEXTPAL";
406
+		case BOBJEXTPAL: return "BOBJEXTPAL";
407
+		default: return "UNHANDLED CASE";
408
+	}
409
+}
410
+
411
+std::string VramConfiguration::describe() {
412
+	std::stringstream ret;
413
+	for(int i=0;i<VRAM_BANKS;i++) {
414
+		ret << (char)(i+'A') << ": " << banks[i].ofs << " " << describePurpose(banks[i].purpose) << std::endl;
415
+	}
416
+	return ret.str();
417
+}*/
418
+
419
+//maps the specified bank to LCDC
420
+static inline void MMU_vram_lcdc(const int bank)
421
+{
422
+	for(int i=0;i<vram_bank_info[bank].num_pages;i++)
423
+	{
424
+		int page = vram_bank_info[bank].page_addr+i;
425
+		vram_lcdc_map[page] = page;
426
+	}
427
+}
428
+
429
+//maps the specified bank to ARM9 at the provided page offset
430
+static inline void MMU_vram_arm9(const int bank, const int offset)
431
+{
432
+	for(int i=0;i<vram_bank_info[bank].num_pages;i++)
433
+	{
434
+		int page = vram_bank_info[bank].page_addr+i;
435
+
436
+		vram_arm9_map[i+offset] = page;
437
+	}
438
+}
439
+
440
+static inline uint8_t* MMU_vram_physical(const int page)
441
+{
442
+	return MMU.ARM9_LCD + (page/**ADDRESS_STEP_16KB*/);
443
+}
444
+
445
+//todo - templateize
446
+static inline void MMU_VRAMmapRefreshBank(const int bank)
447
+{
448
+	int block = bank;
449
+	if(bank >= VRAM_BANK_H) block++;
450
+
451
+	uint8_t VRAMBankCnt = T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x240 + block);
452
+
453
+	//do nothing if the bank isnt enabled
454
+	uint8_t en = VRAMBankCnt & 0x80;
455
+	if(!en) return;
456
+
457
+	int mst,ofs=0;
458
+	switch(bank) {
459
+		case VRAM_BANK_A:
460
+		case VRAM_BANK_B:
461
+			mst = VRAMBankCnt & 3;
462
+			ofs = (VRAMBankCnt>>3) & 3;
463
+			switch(mst)
464
+			{
465
+			case 0: //LCDC
466
+				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
467
+				MMU_vram_lcdc(bank);
468
+				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
469
+				break;
470
+			case 1: //ABG
471
+				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
472
+				MMU_vram_arm9(bank,VRAM_PAGE_ABG+ofs*8);
473
+				break;
474
+			case 2: //AOBJ
475
+				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
476
+				switch(ofs) {
477
+				case 0:
478
+				case 1:
479
+					MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+ofs*8);
480
+					break;
481
+				//default:
482
+					//PROGINFO("Unsupported ofs setting %d for engine A OBJ vram bank %c\n", ofs, 'A'+bank);
483
+				}
484
+				break;
485
+			case 3: //texture
486
+				vramConfiguration.banks[bank].purpose = VramConfiguration::TEX;
487
+				MMU.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
488
+				break;
489
+			default: goto unsupported_mst;
490
+			}
491
+			break;
492
+
493
+		case VRAM_BANK_C:
494
+		case VRAM_BANK_D:
495
+			mst = VRAMBankCnt & 7;
496
+			ofs = (VRAMBankCnt>>3) & 3;
497
+			switch(mst)
498
+			{
499
+			case 0: //LCDC
500
+				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
501
+				MMU_vram_lcdc(bank);
502
+				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
503
+				break;
504
+			case 1: //ABG
505
+				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
506
+				MMU_vram_arm9(bank,VRAM_PAGE_ABG+ofs*8);
507
+				break;
508
+			case 2: //arm7
509
+				vramConfiguration.banks[bank].purpose = VramConfiguration::ARM7;
510
+				if(bank == 2) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 1);
511
+				if(bank == 3) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 2);
512
+				switch(ofs) {
513
+				case 0:
514
+				case 1:
515
+					vram_arm7_map[ofs] = vram_bank_info[bank].page_addr;
516
+					break;
517
+				//default:
518
+					//PROGINFO("Unsupported ofs setting %d for arm7 vram bank %c\n", ofs, 'A'+bank);
519
+				}
520
+
521
+				break;
522
+			case 3: //texture
523
+				vramConfiguration.banks[bank].purpose = VramConfiguration::TEX;
524
+				MMU.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
525
+				break;
526
+			case 4: //BGB or BOBJ
527
+				if(bank == VRAM_BANK_C)  {
528
+					vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
529
+					MMU_vram_arm9(bank,VRAM_PAGE_BBG); //BBG
530
+				} else {
531
+					vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJ;
532
+					MMU_vram_arm9(bank,VRAM_PAGE_BOBJ); //BOBJ
533
+				}
534
+				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
535
+				break;
536
+			default: goto unsupported_mst;
537
+			}
538
+			break;
539
+
540
+		case VRAM_BANK_E:
541
+			mst = VRAMBankCnt & 7;
542
+			//if(((VRAMBankCnt>>3)&3) != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
543
+			switch(mst) {
544
+			case 0: //LCDC
545
+				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
546
+				MMU_vram_lcdc(bank);
547
+				break;
548
+			case 1: //ABG
549
+				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
550
+				MMU_vram_arm9(bank,VRAM_PAGE_ABG);
551
+				break;
552
+			case 2: //AOBJ
553
+				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
554
+				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ);
555
+				break;
556
+			case 3: //texture palette
557
+				vramConfiguration.banks[bank].purpose = VramConfiguration::TEXPAL;
558
+				MMU.texInfo.texPalSlot[0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
559
+				MMU.texInfo.texPalSlot[1] = MMU_vram_physical(vram_bank_info[bank].page_addr+1);
560
+				MMU.texInfo.texPalSlot[2] = MMU_vram_physical(vram_bank_info[bank].page_addr+2);
561
+				MMU.texInfo.texPalSlot[3] = MMU_vram_physical(vram_bank_info[bank].page_addr+3);
562
+				break;
563
+			case 4: //A BG extended palette
564
+				vramConfiguration.banks[bank].purpose = VramConfiguration::ABGEXTPAL;
565
+				MMU.ExtPal[0][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
566
+				MMU.ExtPal[0][1] = MMU.ExtPal[0][0]/* + ADDRESS_STEP_8KB*/;
567
+				MMU.ExtPal[0][2] = MMU.ExtPal[0][1]/* + ADDRESS_STEP_8KB*/;
568
+				MMU.ExtPal[0][3] = MMU.ExtPal[0][2]/* + ADDRESS_STEP_8KB*/;
569
+				break;
570
+			default: goto unsupported_mst;
571
+			}
572
+			break;
573
+
574
+		case VRAM_BANK_F:
575
+		case VRAM_BANK_G: {
576
+			mst = VRAMBankCnt & 7;
577
+			ofs = (VRAMBankCnt>>3) & 3;
578
+			const int pageofslut[] = {0,1,4,5};
579
+			const int pageofs = pageofslut[ofs];
580
+			switch(mst)
581
+			{
582
+			case 0: //LCDC
583
+				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
584
+				MMU_vram_lcdc(bank);
585
+				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
586
+				break;
587
+			case 1: //ABG
588
+				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
589
+				MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs);
590
+				MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs+2); //unexpected mirroring (required by spyro eternal night)
591
+				break;
592
+			case 2: //AOBJ
593
+				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
594
+				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+pageofs);
595
+				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+pageofs+2); //unexpected mirroring - I have no proof, but it is inferred from the ABG above
596
+				break;
597
+			case 3: //texture palette
598
+				vramConfiguration.banks[bank].purpose = VramConfiguration::TEXPAL;
599
+				MMU.texInfo.texPalSlot[pageofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
600
+				break;
601
+			case 4: //A BG extended palette
602
+				switch(ofs) {
603
+				case 0:
604
+				case 1:
605
+					vramConfiguration.banks[bank].purpose = VramConfiguration::ABGEXTPAL;
606
+					MMU.ExtPal[0][ofs*2] = MMU_vram_physical(vram_bank_info[bank].page_addr);
607
+					MMU.ExtPal[0][ofs*2+1] = MMU.ExtPal[0][ofs*2]/* + ADDRESS_STEP_8KB*/;
608
+					break;
609
+				default:
610
+					vramConfiguration.banks[bank].purpose = VramConfiguration::INVALID;
611
+					//PROGINFO("Unsupported ofs setting %d for engine A bgextpal vram bank %c\n", ofs, 'A'+bank);
612
+					break;
613
+				}
614
+				break;
615
+			case 5: //A OBJ extended palette
616
+				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJEXTPAL;
617
+				MMU.ObjExtPal[0][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
618
+				MMU.ObjExtPal[0][1] = MMU.ObjExtPal[0][1]/* + ADDRESS_STEP_8KB*/;
619
+				//if(ofs != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
620
+				break;
621
+			default: goto unsupported_mst;
622
+			}
623
+			break;
624
+		}
625
+
626
+		case VRAM_BANK_H:
627
+			mst = VRAMBankCnt & 3;
628
+			//if(((VRAMBankCnt>>3)&3) != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
629
+			switch(mst)
630
+			{
631
+			case 0: //LCDC
632
+				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
633
+				MMU_vram_lcdc(bank);
634
+				break;
635
+			case 1: //BBG
636
+				vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
637
+				MMU_vram_arm9(bank,VRAM_PAGE_BBG);
638
+				MMU_vram_arm9(bank,VRAM_PAGE_BBG + 4); //unexpected mirroring
639
+				break;
640
+			case 2: //B BG extended palette
641
+				vramConfiguration.banks[bank].purpose = VramConfiguration::BBGEXTPAL;
642
+				MMU.ExtPal[1][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
643
+				MMU.ExtPal[1][1] = MMU.ExtPal[1][0]/* + ADDRESS_STEP_8KB*/;
644
+				MMU.ExtPal[1][2] = MMU.ExtPal[1][1]/* + ADDRESS_STEP_8KB*/;
645
+				MMU.ExtPal[1][3] = MMU.ExtPal[1][2]/* + ADDRESS_STEP_8KB*/;
646
+				break;
647
+			default: goto unsupported_mst;
648
+			}
649
+			break;
650
+
651
+		case VRAM_BANK_I:
652
+			mst = VRAMBankCnt & 3;
653
+			//if(((VRAMBankCnt>>3)&3) != 0) PROGINFO("Bank %i: MST %i OFS %i\n", mst, ofs);
654
+			switch(mst)
655
+			{
656
+			case 0: //LCDC
657
+				vramConfiguration.banks[bank].purpose = VramConfiguration::LCDC;
658
+				MMU_vram_lcdc(bank);
659
+				break;
660
+			case 1: //BBG
661
+				vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
662
+				MMU_vram_arm9(bank,VRAM_PAGE_BBG+2);
663
+				MMU_vram_arm9(bank,VRAM_PAGE_BBG+3); //unexpected mirroring
664
+				break;
665
+			case 2: //BOBJ
666
+				vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJ;
667
+				MMU_vram_arm9(bank,VRAM_PAGE_BOBJ);
668
+				MMU_vram_arm9(bank,VRAM_PAGE_BOBJ+1); //FF3 end scene (lens flare sprite) needs this as it renders a sprite off the end of the 16KB and back around
669
+				break;
670
+			case 3: //B OBJ extended palette
671
+				vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJEXTPAL;
672
+				MMU.ObjExtPal[1][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
673
+				MMU.ObjExtPal[1][1] = MMU.ObjExtPal[1][1]/* + ADDRESS_STEP_8KB*/;
674
+				break;
675
+			default: goto unsupported_mst;
676
+			}
677
+			break;
678
+
679
+
680
+	} //switch(bank)
681
+
682
+	vramConfiguration.banks[bank].ofs = ofs;
683
+
684
+	return;
685
+
686
+unsupported_mst:
687
+	vramConfiguration.banks[bank].purpose = VramConfiguration::INVALID;
688
+	//PROGINFO("Unsupported mst setting %d for vram bank %c\n", mst, 'A'+bank);
689
+}
690
+
691
+void MMU_VRAM_unmap_all()
692
+{
693
+	vramConfiguration.clear();
694
+
695
+	vram_arm7_map[0] = VRAM_PAGE_UNMAPPED;
696
+	vram_arm7_map[1] = VRAM_PAGE_UNMAPPED;
697
+
698
+	for(int i=0;i<VRAM_LCDC_PAGES;i++)
699
+		vram_lcdc_map[i] = VRAM_PAGE_UNMAPPED;
700
+	for(int i=0;i<VRAM_ARM9_PAGES;i++)
701
+		vram_arm9_map[i] = VRAM_PAGE_UNMAPPED;
702
+
703
+	for (int i = 0; i < 4; i++)
704
+	{
705
+		MMU.ExtPal[0][i] = MMU.blank_memory;
706
+		MMU.ExtPal[1][i] = MMU.blank_memory;
707
+	}
708
+
709
+	MMU.ObjExtPal[0][0] = MMU.blank_memory;
710
+	MMU.ObjExtPal[0][1] = MMU.blank_memory;
711
+	MMU.ObjExtPal[1][0] = MMU.blank_memory;
712
+	MMU.ObjExtPal[1][1] = MMU.blank_memory;
713
+
714
+	for(int i=0;i<6;i++)
715
+		MMU.texInfo.texPalSlot[i] = MMU.blank_memory;
716
+
717
+	for(int i=0;i<4;i++)
718
+		MMU.texInfo.textureSlotAddr[i] = MMU.blank_memory;
719
+}
720
+
721
+static inline void MMU_VRAMmapControl(uint8_t block, uint8_t VRAMBankCnt)
722
+{
723
+	//dont handle wram mappings in here
724
+	if(block == 7) {
725
+		//wram
726
+		return;
727
+	}
728
+
729
+	//first, save the texture info so we can check it for changes and trigger purges of the texcache
730
+	MMU_struct::TextureInfo oldTexInfo = MMU.texInfo;
731
+
732
+	//unmap everything
733
+	MMU_VRAM_unmap_all();
734
+
735
+	//unmap VRAM_BANK_C and VRAM_BANK_D from arm7. theyll get mapped again in a moment if necessary
736
+	T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, 0);
737
+
738
+	//write the new value to the reg
739
+	T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x240 + block, VRAMBankCnt);
740
+
741
+	//refresh all bank settings
742
+	//these are enumerated so that we can tune the order they get applied
743
+	//in order to emulate prioritization rules for memory regions
744
+	//with multiple banks mapped.
745
+	//We're probably still not mapping things 100% correctly, but this helped us get closer:
746
+	//goblet of fire "care of magical creatures" maps I and D to BOBJ (the I is an accident)
747
+	//and requires A to override it.
748
+	//This may create other bugs....
749
+	MMU_VRAMmapRefreshBank(VRAM_BANK_I);
750
+	MMU_VRAMmapRefreshBank(VRAM_BANK_H);
751
+	MMU_VRAMmapRefreshBank(VRAM_BANK_G);
752
+	MMU_VRAMmapRefreshBank(VRAM_BANK_F);
753
+	MMU_VRAMmapRefreshBank(VRAM_BANK_E);
754
+	MMU_VRAMmapRefreshBank(VRAM_BANK_D);
755
+	MMU_VRAMmapRefreshBank(VRAM_BANK_C);
756
+	MMU_VRAMmapRefreshBank(VRAM_BANK_B);
757
+	MMU_VRAMmapRefreshBank(VRAM_BANK_A);
758
+
759
+	//printf(vramConfiguration.describe().c_str());
760
+	//printf("vram remapped at vcount=%d\n",nds.VCount);
761
+
762
+	//if texInfo changed, trigger notifications
763
+	if(memcmp(&oldTexInfo,&MMU.texInfo,sizeof(MMU_struct::TextureInfo)))
764
+	{
765
+		//if(!nds.isIn3dVblank())
766
+	//		PROGINFO("Changing texture or texture palette mappings outside of 3d vblank\n");
767
+		//gpu3D->NDS_3D_VramReconfigureSignal();
768
+	}
769
+
770
+	//-------------------------------
771
+	//set up arm9 mirrorings
772
+	//these are probably not entirely accurate. more study will be necessary.
773
+	//in general, we find that it is not uncommon at all for games to accidentally do this.
774
+	//
775
+	//being able to easily do these experiments was one of the primary motivations for this remake of the vram mapping system
776
+
777
+	//see the "unexpected mirroring" comments above for some more mirroring
778
+	//so far "unexpected mirrorings" are tested by combining these games:
779
+	//despereaux - storybook subtitles
780
+	//NSMB - world map sub screen
781
+	//drill spirits EU - mission select (just for control purposes, as it doesnt use H or I)
782
+	//...
783
+	//note that the "unexpected mirroring" items above may at some point rely on being executed in a certain order.
784
+	//(sequentially A..I)
785
+
786
+	const int types[] = {VRAM_PAGE_ABG,VRAM_PAGE_BBG,VRAM_PAGE_AOBJ,VRAM_PAGE_BOBJ};
787
+	const int sizes[] = {32,8,16,8};
788
+	for(int t=0;t<4;t++)
789
+	{
790
+		//the idea here is to pad out the mirrored space with copies of the mappable area,
791
+		//without respect to what is mapped within that mappable area.
792
+		//we hope that this is correct in all cases
793
+		//required for driller spirits in mission select (mapping is simple A,B,C,D to each purpose)
794
+		const int size = sizes[t];
795
+		const int mask = size-1;
796
+		const int type = types[t];
797
+		for(int i=size;i<128;i++)
798
+		{
799
+			const int page = type + i;
800
+			vram_arm9_map[page] = vram_arm9_map[type+(i&mask)];
801
+		}
802
+
803
+		//attempt #1: screen corruption in drill spirits EU
804
+		//it seems like these shouldnt pad out 128K banks (space beyond those should have remained unmapped)
805
+		//int mirrorMask = -1;
806
+		//int type = types[t];
807
+		////if(type==VRAM_PAGE_BOBJ) continue;
808
+		//if(type==VRAM_PAGE_AOBJ) continue;
809
+		//for(int i=0;i<128;i++)
810
+		//{
811
+		//	int page = type + i;
812
+		//	if(vram_arm9_map[page] == VRAM_PAGE_UNMAPPED)
813
+		//	{
814
+		//		if(i==0) break; //can't mirror anything if theres nothing mapped!
815
+		//		if(mirrorMask == -1)
816
+		//			mirrorMask = i-1;
817
+		//		vram_arm9_map[page] = vram_arm9_map[type+(i&mirrorMask)];
818
+		//	}
819
+		//}
820
+	}
821
+
822
+	//-------------------------------
823
+}
824
+
825
+//////////////////////////////////////////////////////////////
826
+//end vram
827
+//////////////////////////////////////////////////////////////
828
+
829
+
830
+
831
+void MMU_Init() {
832
+	//LOG("MMU init\n");
833
+
834
+	memset(&MMU, 0, sizeof(MMU_struct));
835
+
836
+	MMU.CART_ROM = MMU.UNUSED_RAM;
837
+
838
+	//MMU.DTCMRegion = 0x027C0000;
839
+	//even though apps may change dtcm immediately upon startup, this is the correct hardware starting value:
840
+	MMU.DTCMRegion = 0x08000000;
841
+	MMU.ITCMRegion = 0x00000000;
842
+
843
+	IPC_FIFOinit(ARMCPU_ARM9);
844
+	IPC_FIFOinit(ARMCPU_ARM7);
845
+	//GFX_PIPEclear();
846
+	//GFX_FIFOclear();
847
+	//DISP_FIFOinit();
848
+	new(&MMU_new) MMU_struct_new;
849
+
850
+	mc_init(&MMU.fw, MC_TYPE_FLASH);  /* init fw device */
851
+	mc_alloc(&MMU.fw, NDS_FW_SIZE_V1);
852
+	MMU.fw.fp = NULL;
853
+	MMU.fw.isFirmware = true;
854
+
855
+	// Init Backup Memory device, this should really be done when the rom is loaded
856
+	//mc_init(&MMU.bupmem, MC_TYPE_AUTODETECT);
857
+	//mc_alloc(&MMU.bupmem, 1);
858
+	//MMU.bupmem.fp = NULL;
859
+	//rtcInit();
860
+	//addonsInit();
861
+	//slot1Init();
862
+	/*if(Mic_Init() == false)
863
+		INFO("Microphone init failed.\n");
864
+	else
865
+		INFO("Microphone successfully inited.\n");*/
866
+}
867
+
868
+void MMU_DeInit() {
869
+	//LOG("MMU deinit\n");
870
+	/*if (MMU.fw.fp)
871
+		fclose(MMU.fw.fp);*/
872
+	mc_free(&MMU.fw);
873
+	//if (MMU.bupmem.fp)
874
+	//	fclose(MMU.bupmem.fp);
875
+	//mc_free(&MMU.bupmem);
876
+	//addonsClose();
877
+	//slot1Close();
878
+	//Mic_DeInit();
879
+}
880
+
881
+void MMU_Reset()
882
+{
883
+	memset(MMU.ARM9_DTCM, 0, sizeof(MMU.ARM9_DTCM));
884
+	memset(MMU.ARM9_ITCM, 0, sizeof(MMU.ARM9_ITCM));
885
+	memset(MMU.ARM9_LCD,  0, sizeof(MMU.ARM9_LCD));
886
+	memset(MMU.ARM9_OAM,  0, sizeof(MMU.ARM9_OAM));
887
+	memset(MMU.ARM9_REG,  0, sizeof(MMU.ARM9_REG));
888
+	memset(MMU.ARM9_VMEM, 0, sizeof(MMU.ARM9_VMEM));
889
+	memset(MMU.MAIN_MEM,  0, sizeof(MMU.MAIN_MEM));
890
+
891
+	memset(MMU.blank_memory,  0, sizeof(MMU.blank_memory));
892
+	memset(MMU.UNUSED_RAM,    0, sizeof(MMU.UNUSED_RAM));
893
+	memset(MMU.MORE_UNUSED_RAM,    0, sizeof(MMU.UNUSED_RAM));
894
+
895
+	memset(MMU.ARM7_ERAM,     0, sizeof(MMU.ARM7_ERAM));
896
+	memset(MMU.ARM7_REG,      0, sizeof(MMU.ARM7_REG));
897
+	memset(MMU.ARM7_WIRAM,	  0, sizeof(MMU.ARM7_WIRAM));
898
+	memset(MMU.SWIRAM,	  0, sizeof(MMU.SWIRAM));
899
+
900
+	IPC_FIFOinit(ARMCPU_ARM9);
901
+	IPC_FIFOinit(ARMCPU_ARM7);
902
+	//GFX_PIPEclear();
903
+	//GFX_FIFOclear();
904
+	//DISP_FIFOinit();
905
+
906
+	MMU.DTCMRegion = 0x027C0000;
907
+	MMU.ITCMRegion = 0x00000000;
908
+
909
+	memset(MMU.timer,         0, sizeof(uint16_t) * 2 * 4);
910
+	memset(MMU.timerMODE,     0, sizeof(int32_t) * 2 * 4);
911
+	memset(MMU.timerON,       0, sizeof(uint32_t) * 2 * 4);
912
+	memset(MMU.timerRUN,      0, sizeof(uint32_t) * 2 * 4);
913
+	memset(MMU.timerReload,   0, sizeof(uint16_t) * 2 * 4);
914
+
915
+	memset(MMU.reg_IME,       0, sizeof(uint32_t) * 2);
916
+	memset(MMU.reg_IE,        0, sizeof(uint32_t) * 2);
917
+	memset(MMU.reg_IF_bits,   0, sizeof(uint32_t) * 2);
918
+	memset(MMU.reg_IF_pending,   0, sizeof(uint32_t) * 2);
919
+
920
+	memset(MMU.dscard,        0, sizeof(nds_dscard) * 2);
921
+
922
+	MMU.divRunning = 0;
923
+	MMU.divResult = 0;
924
+	MMU.divMod = 0;
925
+	MMU.divCycles = 0;
926
+
927
+	MMU.sqrtRunning = 0;
928
+	MMU.sqrtResult = 0;
929
+	MMU.sqrtCycles = 0;
930
+
931
+	MMU.SPI_CNT = 0;
932
+	MMU.AUX_SPI_CNT = 0;
933
+
934
+	// Enable the sound speakers
935
+	T1WriteWord(MMU.ARM7_REG, 0x304, 0x0001);
936
+
937
+	//MainScreen.offset = 0;
938
+	//SubScreen.offset  = 192;
939
+
940
+	MMU_VRAM_unmap_all();
941
+
942
+	MMU.powerMan_CntReg = 0x00;
943
+	MMU.powerMan_CntRegWritten = false;
944
+	MMU.powerMan_Reg[0] = 0x0B;
945
+	MMU.powerMan_Reg[1] = 0x00;
946
+	MMU.powerMan_Reg[2] = 0x01;
947
+	MMU.powerMan_Reg[3] = 0x00;
948
+
949
+	//rtcInit();
950
+	partie = 1;
951
+	//addonsReset();
952
+	//slot1Reset();
953
+	//Mic_Reset();
954
+	//MMU.gfx3dCycles = 0;
955
+
956
+	memset(MMU.dscard[ARMCPU_ARM9].command, 0, 8);
957
+	MMU.dscard[ARMCPU_ARM9].address = 0;
958
+	MMU.dscard[ARMCPU_ARM9].transfer_count = 0;
959
+	MMU.dscard[ARMCPU_ARM9].mode = CardMode_Normal;
960
+
961
+	memset(MMU.dscard[ARMCPU_ARM7].command, 0, 8);
962
+	MMU.dscard[ARMCPU_ARM7].address = 0;
963
+	MMU.dscard[ARMCPU_ARM7].transfer_count = 0;
964
+	MMU.dscard[ARMCPU_ARM7].mode = CardMode_Normal;
965
+
966
+	//HACK!!!
967
+	//until we improve all our session tracking stuff, we need to save the backup memory filename
968
+	std::string bleh = MMU_new.backupDevice.getFilename();
969
+	BackupDevice tempBackupDevice;
970
+	//bool bleh2 = MMU_new.backupDevice.isMovieMode;
971
+	//if(bleh2) tempBackupDevice = MMU_new.backupDevice;
972
+	reconstruct(&MMU_new);
973
+	/*if(bleh2) {
974
+		MMU_new.backupDevice = tempBackupDevice;
975
+		MMU_new.backupDevice.reset_hardware();
976
+	}
977
+	else*/ MMU_new.backupDevice.load_rom(bleh.c_str());
978
+
979
+	MMU_timing.arm7codeFetch.Reset();
980
+	MMU_timing.arm7dataFetch.Reset();
981
+	MMU_timing.arm9codeFetch.Reset();
982
+	MMU_timing.arm9dataFetch.Reset();
983
+	MMU_timing.arm9codeCache.Reset();
984
+	MMU_timing.arm9dataCache.Reset();
985
+}
986
+
987
+void SetupMMU(bool debugConsole, bool dsi) {
988
+	if(debugConsole) _MMU_MAIN_MEM_MASK = 0x7FFFFF;
989
+	else _MMU_MAIN_MEM_MASK = 0x3FFFFF;
990
+	if(dsi) _MMU_MAIN_MEM_MASK = 0xFFFFFF;
991
+	_MMU_MAIN_MEM_MASK16 = _MMU_MAIN_MEM_MASK & ~1;
992
+	_MMU_MAIN_MEM_MASK32 = _MMU_MAIN_MEM_MASK & ~3;
993
+}
994
+
995
+void MMU_setRom(uint8_t * rom, uint32_t)
996
+{
997
+	MMU.CART_ROM = rom;
998
+}
999
+
1000
+void MMU_unsetRom()
1001
+{
1002
+	MMU.CART_ROM=MMU.UNUSED_RAM;
1003
+}
1004
+
1005
+static void execsqrt() {
1006
+	uint32_t ret;
1007
+	uint8_t mode = MMU_new.sqrt.mode;
1008
+	MMU_new.sqrt.busy = 1;
1009
+
1010
+	if (mode) {
1011
+		uint64_t v = T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B8);
1012
+		ret = (uint32_t)isqrt(v);
1013
+	} else {
1014
+		uint32_t v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B8);
1015
+		ret = (uint32_t)isqrt(v);
1016
+	}
1017
+
1018
+	//clear the result while the sqrt unit is busy
1019
+	//todo - is this right? is it reasonable?
1020
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B4, 0);
1021
+
1022
+	MMU.sqrtCycles = nds_timer + 26;
1023
+	MMU.sqrtResult = ret;
1024
+	MMU.sqrtRunning = true;
1025
+	NDS_Reschedule();
1026
+}
1027
+
1028
+static void execdiv() {
1029
+
1030
+	int64_t num,den;
1031
+	int64_t res,mod;
1032
+	uint8_t mode = MMU_new.div.mode;
1033
+	MMU_new.div.busy = 1;
1034
+	MMU_new.div.div0 = 0;
1035
+
1036
+	switch(mode)
1037
+	{
1038
+	case 0:	// 32/32
1039
+		num = (int64_t) (int32_t) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
1040
+		den = (int64_t) (int32_t) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
1041
+		MMU.divCycles = nds_timer + 36;
1042
+		break;
1043
+	case 1:	// 64/32
1044
+	case 3: //gbatek says this is same as mode 1
1045
+		num = (int64_t) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
1046
+		den = (int64_t) (int32_t) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
1047
+		MMU.divCycles = nds_timer + 68;
1048
+		break;
1049
+	case 2:	// 64/64
1050
+	default:
1051
+		num = (int64_t) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
1052
+		den = (int64_t) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
1053
+		MMU.divCycles = nds_timer + 68;
1054
+		break;
1055
+	}
1056
+
1057
+	if(den==0)
1058
+	{
1059
+		res = ((num < 0) ? 1 : -1);
1060
+		mod = num;
1061
+
1062
+		// the DIV0 flag in DIVCNT is set only if the full 64bit DIV_DENOM value is zero, even in 32bit mode
1063
+		if ((uint64_t)T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298) == 0)
1064
+			MMU_new.div.div0 = 1;
1065
+	}
1066
+	else
1067
+	{
1068
+		res = num / den;
1069
+		mod = num % den;
1070
+	}
1071
+
1072
+	/*DIVLOG("DIV %08X%08X / %08X%08X = %08X%08X\r\n", (uint32_t)(num>>32), (uint32_t)num,
1073
+							(uint32_t)(den>>32), (uint32_t)den,
1074
+							(uint32_t)(res>>32), (uint32_t)res);*/
1075
+
1076
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A0, 0);
1077
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A4, 0);
1078
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A8, 0);
1079
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2AC, 0);
1080
+
1081
+	MMU.divResult = res;
1082
+	MMU.divMod = mod;
1083
+	MMU.divRunning = true;
1084
+	NDS_Reschedule();
1085
+}
1086
+
1087
+DSI_TSC::DSI_TSC()
1088
+{
1089
+	for(unsigned i=0;i<ARRAY_SIZE(registers);i++)
1090
+		registers[i] = 0x00;
1091
+	reset_command();
1092
+}
1093
+
1094
+void DSI_TSC::reset_command()
1095
+{
1096
+	state = 0;
1097
+	readcount = 0;
1098
+	read_flag = 1;
1099
+}
1100
+
1101
+uint16_t DSI_TSC::write16(uint16_t val)
1102
+{
1103
+	uint16_t ret;
1104
+	switch(state)
1105
+	{
1106
+	case 0:
1107
+		reg_selection = (val>>1)&0x7F;
1108
+		read_flag = val&1;
1109
+		state = 1;
1110
+		return read16();
1111
+	case 1:
1112
+		if(read_flag)
1113
+		{ }
1114
+		else
1115
+		{
1116
+			registers[reg_selection] = (uint8_t)val;
1117
+		}
1118
+		ret = read16();
1119
+		reg_selection++;
1120
+		reg_selection &= 0x7F;
1121
+		return ret;
1122
+	}
1123
+	return 0;
1124
+}
1125
+
1126
+uint16_t DSI_TSC::read16()
1127
+{
1128
+	uint8_t page = registers[0];
1129
+	switch(page)
1130
+	{
1131
+	case 3: //page 3
1132
+		switch(reg_selection)
1133
+		{
1134
+		case 9:
1135
+			/*if(nds.isTouch)
1136
+				return 0;
1137
+			else */return 0x40;
1138
+			break;
1139
+		case 14:
1140
+			/*if(nds.isTouch)
1141
+				return 0;
1142
+			else */return 0x02;
1143
+			break;
1144
+		}
1145
+		break;
1146
+
1147
+	case 252: //page 252
1148
+		switch(reg_selection)
1149
+		{
1150
+		//high byte of X:
1151
+		/*case 1: case 3: case 5: case 7: case 9:
1152
+			return (nds.scr_touchX>>8)&0xFF;
1153
+
1154
+		//low byte of X:
1155
+		case 2: case 4: case 6: case 8: case 10:
1156
+			return nds.scr_touchX&0xFF;
1157
+
1158
+		//high byte of Y:
1159
+		case 11: case 13: case 15: case 17: case 19:
1160
+			return (nds.scr_touchY>>8)&0xFF;
1161
+
1162
+		//low byte of Y:
1163
+		case 12: case 14: case 16: case 18: case 20:
1164
+			return nds.scr_touchY&0xFF;*/
1165
+
1166
+		default:
1167
+			return 0xFF;
1168
+		}
1169
+		break;
1170
+	} //switch(page)
1171
+
1172
+	//unknown page or register
1173
+	return 0xFF;
1174
+}
1175
+
1176
+/*bool DSI_TSC::save_state(EMUFILE* os)
1177
+{
1178
+	uint32_t version = 0;
1179
+	write32le(version,os);
1180
+
1181
+	write8le(reg_selection,os);
1182
+	write8le(read_flag,os);
1183
+	write32le(state,os);
1184
+	write32le(readcount,os);
1185
+	for(int i=0;i<ARRAY_SIZE(registers);i++)
1186
+		write8le(registers[i],os);
1187
+
1188
+	return true;
1189
+}*/
1190
+
1191
+/*bool DSI_TSC::load_state(EMUFILE* is)
1192
+{
1193
+	uint32_t version;
1194
+	read32le(&version,is);
1195
+
1196
+	read8le(&reg_selection,is);
1197
+	read8le(&read_flag,is);
1198
+	read32le(&state,is);
1199
+	read32le(&readcount,is);
1200
+	for(int i=0;i<ARRAY_SIZE(registers);i++)
1201
+		read8le(&registers[i],is);
1202
+
1203
+	return true;
1204
+}*/
1205
+
1206
+// TODO:
1207
+// NAND flash support (used in Made in Ore/WarioWare D.I.Y.)
1208
+template<int PROCNUM>
1209
+void FASTCALL MMU_writeToGCControl(uint32_t val)
1210
+{
1211
+	const int TEST_PROCNUM = PROCNUM;
1212
+	nds_dscard& card = MMU.dscard[TEST_PROCNUM];
1213
+
1214
+	memcpy(&card.command[0], &MMU.MMU_MEM[TEST_PROCNUM][0x40][0x1A8], 8);
1215
+
1216
+	card.blocklen = 0;
1217
+	slot1_device.write32(PROCNUM,0xFFFFFFFF,val); //Special case for some flashcarts
1218
+	if(card.blocklen==0x01020304) return;
1219
+
1220
+	if(!(val & 0x80000000))
1221
+	{
1222
+		card.address = 0;
1223
+		card.transfer_count = 0;
1224
+
1225
+		val &= 0x7F7FFFFF;
1226
+		T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1227
+		return;
1228
+	}
1229
+
1230
+	uint32_t shift = (val>>24&7);
1231
+	if(shift == 7)
1232
+		card.transfer_count = 1;
1233
+	else if(shift == 0)
1234
+		card.transfer_count = 0;
1235
+	else
1236
+		card.transfer_count = (0x100<<shift)/4;
1237
+
1238
+	switch (card.mode)
1239
+	{
1240
+	case CardMode_Normal:
1241
+		break;
1242
+
1243
+	case CardMode_KEY1:
1244
+		{
1245
+			// TODO
1246
+			//INFO("Cartridge: KEY1 mode unsupported.\n");
1247
+
1248
+			card.address = 0;
1249
+			card.transfer_count = 0;
1250
+
1251
+			val &= 0x7F7FFFFF;
1252
+			T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1253
+			return;
1254
+		}
1255
+		break;
1256
+	case CardMode_KEY2:
1257
+			//INFO("Cartridge: KEY2 mode unsupported.\n");
1258
+		break;
1259
+	}
1260
+
1261
+	switch(card.command[0])
1262
+	{
1263
+	case 0x9F: //Dummy
1264
+		card.address = 0;
1265
+		card.transfer_count = 0x800;
1266
+		break;
1267
+
1268
+	//case 0x90: //Get ROM chip ID
1269
+	//	break;
1270
+
1271
+	case 0x3C: //Switch to KEY1 mode
1272
+		card.mode = CardMode_KEY1;
1273
+		break;
1274
+
1275
+	default:
1276
+		//fall through to the special slot1 handler
1277
+		slot1_device.write32(TEST_PROCNUM, REG_GCROMCTRL,val);
1278
+		break;
1279
+	}
1280
+
1281
+	if(card.transfer_count == 0)
1282
+	{
1283
+		val &= 0x7F7FFFFF;
1284
+		T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1285
+		return;
1286
+	}
1287
+
1288
+    val |= 0x00800000;
1289
+    T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val);
1290
+
1291
+	// Launch DMA if start flag was set to "DS Cart"
1292
+	//printf("triggering card dma\n");
1293
+	triggerDma(EDMAMode_Card);
1294
+}
1295
+
1296
+
1297
+
1298
+template<int PROCNUM>
1299
+uint32_t MMU_readFromGC()
1300
+{
1301
+	const int TEST_PROCNUM = PROCNUM;
1302
+
1303
+	nds_dscard& card = MMU.dscard[TEST_PROCNUM];
1304
+	uint32_t val = 0;
1305
+
1306
+	if(card.transfer_count == 0)
1307
+		return 0;
1308
+
1309
+	switch(card.command[0])
1310
+	{
1311
+		case 0x9F: //Dummy
1312
+			val = 0xFFFFFFFF;
1313
+			break;
1314
+
1315
+		case 0x3C: //Switch to KEY1 mode
1316
+			val = 0xFFFFFFFF;
1317
+			break;
1318
+
1319
+		default:
1320
+			val = slot1_device.read32(TEST_PROCNUM, REG_GCDATAIN);
1321
+			break;
1322
+	}
1323
+
1324
+	card.address += 4;	// increment address
1325
+
1326
+	card.transfer_count--;	// update transfer counter
1327
+	if(card.transfer_count) // if transfer is not ended
1328
+		return val;	// return data
1329
+
1330
+	// transfer is done
1331
+	T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4,
1332
+		T1ReadLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4) & 0x7F7FFFFF);
1333
+
1334
+	// if needed, throw irq for the end of transfer
1335
+	if(MMU.AUX_SPI_CNT & 0x4000)
1336
+		NDS_makeIrq(TEST_PROCNUM, IRQ_BIT_GC_TRANSFER_COMPLETE);
1337
+
1338
+	return val;
1339
+}
1340
+
1341
+
1342
+
1343
+//does some validation on the game's choice of IF value, correcting it if necessary
1344
+/*static void validateIF_arm9()
1345
+{
1346
+}*/
1347
+
1348
+template<int PROCNUM> static void REG_IF_WriteByte(uint32_t addr, uint8_t val)
1349
+{
1350
+	//the following bits are generated from logic and should not be affected here
1351
+	//Bit 21    NDS9 only: Geometry Command FIFO
1352
+	//arm9: IF &= ~0x00200000;
1353
+	//arm7: IF &= ~0x00000000;
1354
+	//UPDATE IN setIF() ALSO!!!!!!!!!!!!!!!!
1355
+	//UPDATE IN mmu_loadstate ALSO!!!!!!!!!!!!
1356
+	if(addr==2)
1357
+	{
1358
+		if(PROCNUM==ARMCPU_ARM9)
1359
+			val &= ~0x20;
1360
+		else
1361
+			val &= ~0x00;
1362
+	}
1363
+
1364
+	//ZERO 01-dec-2010 : I am no longer sure this approach is correct.. it proved to be wrong for IPC fifo.......
1365
+	//it seems as if IF bits should always be cached (only the user can clear them)
1366
+
1367
+	MMU.reg_IF_bits[PROCNUM] &= (~(((uint32_t)val)<<(addr<<3)));
1368
+	NDS_Reschedule();
1369
+}
1370
+
1371
+template<int PROCNUM> static void REG_IF_WriteWord(uint32_t addr,uint16_t val)
1372
+{
1373
+	REG_IF_WriteByte<PROCNUM>(addr,val&0xFF);
1374
+	REG_IF_WriteByte<PROCNUM>(addr+1,(val>>8)&0xFF);
1375
+}
1376
+
1377
+template<int PROCNUM> static void REG_IF_WriteLong(uint32_t val)
1378
+{
1379
+	REG_IF_WriteByte<PROCNUM>(0,val&0xFF);
1380
+	REG_IF_WriteByte<PROCNUM>(1,(val>>8)&0xFF);
1381
+	REG_IF_WriteByte<PROCNUM>(2,(val>>16)&0xFF);
1382
+	REG_IF_WriteByte<PROCNUM>(3,(val>>24)&0xFF);
1383
+}
1384
+
1385
+template<int PROCNUM>
1386
+uint32_t MMU_struct::gen_IF()
1387
+{
1388
+	uint32_t IF = reg_IF_bits[PROCNUM];
1389
+
1390
+	/*if(PROCNUM==ARMCPU_ARM9)
1391
+	{
1392
+		//according to gbatek, these flags are forced on until the condition is removed.
1393
+		//no proof of this though...
1394
+		switch(MMU_new.gxstat.gxfifo_irq)
1395
+		{
1396
+		case 0: //never
1397
+			break;
1398
+		case 1: //less than half full
1399
+			if(MMU_new.gxstat.fifo_low)
1400
+				IF |= IRQ_MASK_ARM9_GXFIFO;
1401
+			break;
1402
+		case 2: //empty
1403
+			if(MMU_new.gxstat.fifo_empty)
1404
+				IF |= IRQ_MASK_ARM9_GXFIFO;
1405
+			break;
1406
+		case 3: //reserved/unknown
1407
+			break;
1408
+		}
1409
+	}*/
1410
+
1411
+	return IF;
1412
+}
1413
+
1414
+/*static void writereg_DISP3DCNT(const int size, const uint32_t adr, const uint32_t val)
1415
+{
1416
+	//UGH. rewrite this shite to use individual values and reconstruct the return value instead of packing things in this !@#)ing register
1417
+
1418
+	//nanostray2 cutscene will test this vs old desmumes by using some kind of 32bit access for setting up this reg for cutscenes
1419
+	switch(size)
1420
+	{
1421
+	case 8:
1422
+		switch(adr)
1423
+		{
1424
+		case REG_DISPA_DISP3DCNT:
1425
+			MMU.reg_DISP3DCNT_bits &= 0xFFFFFF00;
1426
+			MMU.reg_DISP3DCNT_bits |= val;
1427
+			//gfx3d_Control(MMU.reg_DISP3DCNT_bits);
1428
+			break;
1429
+		case REG_DISPA_DISP3DCNT+1:
1430
+			{
1431
+				uint32_t myval = (val & ~0x30) | (~val & ((MMU.reg_DISP3DCNT_bits>>8) & 0x30)); // bits 12,13 are ack bits
1432
+				myval &= 0x7F; //top bit isnt connected
1433
+				MMU.reg_DISP3DCNT_bits = MMU.reg_DISP3DCNT_bits&0xFFFF00FF;
1434
+				MMU.reg_DISP3DCNT_bits |= (myval<<8);
1435
+				//gfx3d_Control(MMU.reg_DISP3DCNT_bits);
1436
+			}
1437
+			break;
1438
+		}
1439
+		break;
1440
+	case 16:
1441
+	case 32:
1442
+		writereg_DISP3DCNT(8,adr,val&0xFF);
1443
+		writereg_DISP3DCNT(8,adr+1,(val>>8)&0xFF);
1444
+		break;
1445
+	}
1446
+}*/
1447
+
1448
+/*static uint32_t readreg_DISP3DCNT(const int size, const uint32_t adr)
1449
+{
1450
+	//UGH. rewrite this shite to use individual values and reconstruct the return value instead of packing things in this !@#)ing register
1451
+	switch(size)
1452
+	{
1453
+	case 8:
1454
+		switch(adr)
1455
+		{
1456
+		case REG_DISPA_DISP3DCNT:
1457
+			return MMU.reg_DISP3DCNT_bits & 0xFF;
1458
+		case REG_DISPA_DISP3DCNT+1:
1459
+			return ((MMU.reg_DISP3DCNT_bits)>>8)& 0xFF;
1460
+		}
1461
+		break;
1462
+	case 16:
1463
+	case 32:
1464
+		return readreg_DISP3DCNT(8,adr)|(readreg_DISP3DCNT(8,adr+1)<<8);
1465
+	}
1466
+	assert(false);
1467
+	return 0;
1468
+}*/
1469
+
1470
+
1471
+/*static uint32_t readreg_POWCNT1(const int size, const uint32_t adr) {
1472
+	switch(size)
1473
+	{
1474
+	case 8:
1475
+		switch(adr)
1476
+		{
1477
+		case REG_POWCNT1: {
1478
+			uint8_t ret = 0;
1479
+			ret |= nds.power1.lcd?BIT(0):0;
1480
+			ret |= nds.power1.gpuMain?BIT(1):0;
1481
+			ret |= nds.power1.gfx3d_render?BIT(2):0;
1482
+			ret |= nds.power1.gfx3d_geometry?BIT(3):0;
1483
+			return ret;
1484
+			}
1485
+		case REG_POWCNT1+1: {
1486
+			uint8_t ret = 0;
1487
+			ret |= nds.power1.gpuSub?BIT(1):0;
1488
+			ret |= nds.power1.dispswap?BIT(7):0;
1489
+			return ret;
1490
+			}
1491
+		}
1492
+	case 16:
1493
+	case 32:
1494
+		return readreg_POWCNT1(8,adr)|(readreg_POWCNT1(8,adr+1)<<8);
1495
+	}
1496
+	assert(false);
1497
+	return 0;
1498
+}*/
1499
+/*static void writereg_POWCNT1(const int size, const uint32_t adr, const uint32_t val) {
1500
+	switch(size)
1501
+	{
1502
+	case 8:
1503
+		switch(adr)
1504
+		{
1505
+		case REG_POWCNT1:
1506
+			nds.power1.lcd = BIT0(val);
1507
+			nds.power1.gpuMain = BIT1(val);
1508
+			nds.power1.gfx3d_render = BIT2(val);
1509
+			nds.power1.gfx3d_geometry = BIT3(val);
1510
+			break;
1511
+		case REG_POWCNT1+1:
1512
+			nds.power1.gpuSub = BIT1(val);
1513
+			nds.power1.dispswap = BIT7(val);
1514
+			if(nds.power1.dispswap)
1515
+			{
1516
+				//printf("Main core on top (vcount=%d)\n",nds.VCount);
1517
+				//MainScreen.offset = 0;
1518
+				//SubScreen.offset = 192;
1519
+			}
1520
+			else
1521
+			{
1522
+				//printf("Main core on bottom (vcount=%d)\n",nds.VCount);
1523
+				//MainScreen.offset = 192;
1524
+				//SubScreen.offset = 0;
1525
+			}
1526
+			break;
1527
+		}
1528
+		break;
1529
+	case 16:
1530
+	case 32:
1531
+		writereg_POWCNT1(8,adr,val&0xFF);
1532
+		writereg_POWCNT1(8,adr+1,(val>>8)&0xFF);
1533
+		break;
1534
+	}
1535
+}*/
1536
+
1537
+static inline void MMU_IPCSync(uint8_t proc, uint32_t val)
1538
+{
1539
+	//INFO("IPC%s sync 0x%04X (0x%02X|%02X)\n", proc?"7":"9", val, val >> 8, val & 0xFF);
1540
+	uint32_t sync_l = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x180) & 0xFFFF;
1541
+	uint32_t sync_r = T1ReadLong(MMU.MMU_MEM[proc^1][0x40], 0x180) & 0xFFFF;
1542
+
1543
+	sync_l = ( sync_l & 0x000F ) | ( val & 0x0F00 );
1544
+	sync_r = ( sync_r & 0x6F00 ) | ( (val >> 8) & 0x000F );
1545
+
1546
+	sync_l |= val & 0x6000;
1547
+
1548
+	/*if(nds.ensataEmulation && proc==1 && nds.ensataIpcSyncCounter<9) {
1549
+		uint32_t iteration = (val&0x0F00)>>8;*/
1550
+
1551
+		/*if(iteration==8-nds.ensataIpcSyncCounter)
1552
+			nds.ensataIpcSyncCounter++;
1553
+		else printf("ERROR: ENSATA IPC SYNC HACK FAILED; BAD THINGS MAY HAPPEN\n");*/
1554
+
1555
+		//for some reason, the arm9 doesn't handshake when ensata is detected.
1556
+		//so we complete the protocol here, which is to mirror the values 8..0 back to
1557
+		//the arm7 as they are written by the arm7
1558
+		/*sync_r &= 0xF0FF;
1559
+		sync_r |= (iteration<<8);
1560
+		sync_l &= 0xFFF0;
1561
+		sync_l |= iteration;
1562
+	}*/
1563
+
1564
+	T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, sync_l);
1565
+	T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, sync_r);
1566
+
1567
+	if ((sync_l & IPCSYNC_IRQ_SEND) && (sync_r & IPCSYNC_IRQ_RECV))
1568
+		NDS_makeIrq(proc^1, IRQ_BIT_IPCSYNC);
1569
+
1570
+	NDS_Reschedule();
1571
+}
1572
+
1573
+static inline uint16_t read_timer(int proc, int timerIndex)
1574
+{
1575
+	//chained timers are always up to date
1576
+	if(MMU.timerMODE[proc][timerIndex] == 0xFFFF)
1577
+		return MMU.timer[proc][timerIndex];
1578
+
1579
+	//sometimes a timer will be read when it is not enabled.
1580
+	//we should have the value cached
1581
+	if(!MMU.timerON[proc][timerIndex])
1582
+		return MMU.timer[proc][timerIndex];
1583
+
1584
+	//for unchained timers, we do not keep the timer up to date. its value will need to be calculated here
1585
+	int32_t diff = (int32_t)(nds.timerCycle[proc][timerIndex] - nds_timer);
1586
+	assert(diff>=0);
1587
+	if(diff<0)
1588
+		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: TIME READ DIFF < 0 (%d) (%d) (%d)\n",diff,timerIndex,MMU.timerMODE[proc][timerIndex]);
1589
+
1590
+	int32_t units = diff / (1<<MMU.timerMODE[proc][timerIndex]);
1591
+	int32_t ret;
1592
+
1593
+	if(units==65536)
1594
+		ret = 0; //I'm not sure why this is happening...
1595
+		//whichever instruction setup this counter should advance nds_timer (I think?) and the division should truncate down to 65535 immediately
1596
+	else if(units>65536) {
1597
+		printf("NEW EMULOOP BAD NEWS PLEASE REPORT: UNITS %d:%d = %d\n",proc,timerIndex,units);
1598
+		ret = 0;
1599
+	}
1600
+	else ret = 65535 - units;
1601
+
1602
+	return static_cast<uint16_t>(ret);
1603
+}
1604
+
1605
+static inline void write_timer(int proc, int timerIndex, uint16_t val)
1606
+{
1607
+#if 0
1608
+	int mask		= ((val&0x80)>>7) << timerIndex;
1609
+	MMU.CheckTimers = (MMU.CheckTimers & (~mask)) | mask;
1610
+#endif
1611
+
1612
+	if(val&0x80)
1613
+		MMU.timer[proc][timerIndex] = MMU.timerReload[proc][timerIndex];
1614
+	else
1615
+	{
1616
+		if(MMU.timerON[proc][timerIndex])
1617
+			//read the timer value one last time
1618
+			MMU.timer[proc][timerIndex] = read_timer(proc,timerIndex);
1619
+	}
1620
+
1621
+	MMU.timerON[proc][timerIndex] = val & 0x80;
1622
+
1623
+	switch(val&7)
1624
+	{
1625
+		case 0 :
1626
+			MMU.timerMODE[proc][timerIndex] = 0+1;
1627
+			break;
1628
+		case 1 :
1629
+			MMU.timerMODE[proc][timerIndex] = 6+1;
1630
+			break;
1631
+		case 2 :
1632
+			MMU.timerMODE[proc][timerIndex] = 8+1;
1633
+			break;
1634
+		case 3 :
1635
+			MMU.timerMODE[proc][timerIndex] = 10+1;
1636
+			break;
1637
+		default :
1638
+			MMU.timerMODE[proc][timerIndex] = 0xFFFF;
1639
+			break;
1640
+	}
1641
+
1642
+	int remain = 65536 - MMU.timerReload[proc][timerIndex];
1643
+	nds.timerCycle[proc][timerIndex] = nds_timer + (remain<<MMU.timerMODE[proc][timerIndex]);
1644
+
1645
+	T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x102+timerIndex*4, val);
1646
+	NDS_RescheduleTimers();
1647
+}
1648
+
1649
+//extern CACHE_ALIGN MatrixStack	mtxStack[4];
1650
+uint32_t TGXSTAT::read32()
1651
+{
1652
+	uint32_t ret = 0;
1653
+
1654
+	ret |= tb|(tr<<1);
1655
+
1656
+	//int _hack_getMatrixStackLevel(int which);
1657
+
1658
+	// stack position always equal zero. possible timings is wrong
1659
+	// using in "The Wild West"
1660
+	//ret |= ((_hack_getMatrixStackLevel(0) << 13) | (_hack_getMatrixStackLevel(1) << 8)); //matrix stack levels //no proof that these are needed yet
1661
+
1662
+	ret |= sb<<14;	//stack busy
1663
+	ret |= se<<15;
1664
+	ret |= 255<<16;//(std::min(gxFIFO.size,(uint32_t)255))<<16;
1665
+	//if(gxFIFO.size>=255) ret |= BIT(24); //fifo full
1666
+	//if(gxFIFO.size<128) ret |= BIT(25); //fifo half
1667
+	//if(gxFIFO.size==0) ret |= BIT(26); //fifo empty
1668
+	//determine busy flag.
1669
+	//if we're waiting for a flush, we're busy
1670
+	//if(isSwapBuffers) ret |= BIT(27);
1671
+	//if fifo is nonempty, we're busy
1672
+	//if(gxFIFO.size!=0) ret |= BIT(27);
1673
+
1674
+	ret |= ((gxfifo_irq & 0x3) << 30); //user's irq flags
1675
+
1676
+	//printf("vc=%03d Returning gxstat read: %08X\n",nds.VCount,ret);
1677
+
1678
+	//ret = (2 << 8);
1679
+	//INFO("gxSTAT 0x%08X (proj %i, pos %i)\n", ret, _hack_getMatrixStackLevel(1), _hack_getMatrixStackLevel(2));
1680
+	return ret;
1681
+}
1682
+
1683
+void TGXSTAT::write32(const uint32_t val)
1684
+{
1685
+	gxfifo_irq = (val>>30)&3;
1686
+	if(BIT15(val))
1687
+	{
1688
+		// Writing "1" to Bit15 does reset the Error Flag (Bit15),
1689
+		// and additionally resets the Projection Stack Pointer (Bit13)
1690
+		//mtxStack[0].position = 0;
1691
+		se = 0; //clear stack error flag
1692
+	}
1693
+	//printf("gxstat write: %08X while gxfifo.size=%d\n",val,gxFIFO.size);
1694
+
1695
+		//if (val & (1<<29))		// clear? (only in homebrew?)
1696
+	//{
1697
+	//	GFX_PIPEclear();
1698
+	//	GFX_FIFOclear();
1699
+	//	return;
1700
+	//}
1701
+}
1702
+
1703
+/*void TGXSTAT::savestate(EMUFILE *f)
1704
+{
1705
+	write32le(1,f); //version
1706
+	write8le(tb,f); write8le(tr,f); write8le(se,f); write8le(gxfifo_irq,f); write8le(sb,f);
1707
+}*/
1708
+bool TGXSTAT::loadstate(EMUFILE *f)
1709
+{
1710
+	uint32_t version;
1711
+	if(read32le(&version,f) != 1) return false;
1712
+	if(version > 1) return false;
1713
+
1714
+	read8le(&tb,f); read8le(&tr,f); read8le(&se,f); read8le(&gxfifo_irq,f);
1715
+	if (version >= 1)
1716
+		read8le(&sb,f);
1717
+
1718
+	return true;
1719
+}
1720
+
1721
+//this could be inlined...
1722
+void MMU_struct_new::write_dma(const int proc, const int size, const uint32_t _adr, const uint32_t val)
1723
+{
1724
+	//printf("%08lld -- write_dma: %d %d %08X %08X\n",nds_timer,proc,size,_adr,val);
1725
+	const uint32_t adr = _adr - _REG_DMA_CONTROL_MIN;
1726
+	const uint32_t chan = adr/12;
1727
+	const uint32_t regnum = (adr - chan*12)>>2;
1728
+
1729
+	if(proc==0&&chan==0)
1730
+	{
1731
+		//int zzz=9;
1732
+	}
1733
+
1734
+	if(proc==1) {
1735
+		//int zzz=9;
1736
+	}
1737
+
1738
+	MMU_new.dma[proc][chan].regs[regnum]->write(size,adr,val);
1739
+}
1740
+
1741
+
1742
+//this could be inlined...
1743
+uint32_t MMU_struct_new::read_dma(const int proc, const int size, const uint32_t _adr)
1744
+{
1745
+	const uint32_t adr = _adr - _REG_DMA_CONTROL_MIN;
1746
+	const uint32_t chan = adr/12;
1747
+	const uint32_t regnum = (adr - chan*12)>>2;
1748
+
1749
+	const uint32_t temp = MMU_new.dma[proc][chan].regs[regnum]->read(size,adr);
1750
+	//printf("%08lld --  read_dma: %d %d %08X = %08X\n",nds_timer,proc,size,_adr,temp);
1751
+
1752
+
1753
+
1754
+	if(temp == 0xAF00 && size == 16)
1755
+	{
1756
+		//int zzz=9;
1757
+	}
1758
+
1759
+	return temp;
1760
+}
1761
+
1762
+MMU_struct_new::MMU_struct_new()
1763
+{
1764
+	for(int i=0;i<2;i++)
1765
+		for(int j=0;j<4;j++) {
1766
+			dma[i][j].procnum = i;
1767
+			dma[i][j].chan = j;
1768
+		}
1769
+}
1770
+
1771
+bool DmaController::loadstate(EMUFILE* f)
1772
+{
1773
+	uint32_t version;
1774
+	if(read32le(&version,f) != 1) return false;
1775
+	if(version >1) return false;
1776
+
1777
+	read8le(&enable,f); read8le(&irq,f); read8le(&repeatMode,f); read8le(&_startmode,f);
1778
+	read8le(&userEnable,f);
1779
+	read32le(&wordcount,f);
1780
+	uint8_t temp;
1781
+	read8le(&temp,f); startmode = (EDMAMode)temp;
1782
+	read8le(&temp,f); bitWidth = (EDMABitWidth)temp;
1783
+	read8le(&temp,f); sar = (EDMASourceUpdate)temp;
1784
+	read8le(&temp,f); dar = (EDMADestinationUpdate)temp;
1785
+	read32le(&saddr,f); read32le(&daddr,f);
1786
+	read32le(reinterpret_cast<uint32_t *>(&dmaCheck),f); read32le(reinterpret_cast<uint32_t *>(&running),f); read32le(reinterpret_cast<uint32_t *>(&paused),f); read32le(reinterpret_cast<uint32_t *>(&triggered),f);
1787
+	read64le(&nextEvent,f);
1788
+
1789
+	if(version==1)
1790
+	{
1791
+		read32le(&saddr_user,f);
1792
+		read32le(&daddr_user,f);
1793
+	}
1794
+
1795
+	return true;
1796
+}
1797
+
1798
+/*void DmaController::savestate(EMUFILE *f)
1799
+{
1800
+	write32le(1,f); //version
1801
+	write8le(enable,f); write8le(irq,f); write8le(repeatMode,f); write8le(_startmode,f);
1802
+	write8le(userEnable,f);
1803
+	write32le(wordcount,f);
1804
+	write8le(startmode,f);
1805
+	write8le(bitWidth,f);
1806
+	write8le(sar,f);
1807
+	write8le(dar,f);
1808
+	write32le(saddr,f); write32le(daddr,f);
1809
+	write32le(check,f); write32le(running,f); write32le(paused,f); write32le(triggered,f);
1810
+	write64le(nextEvent,f);
1811
+	write32le(saddr_user,f);
1812
+	write32le(daddr_user,f);
1813
+}*/
1814
+
1815
+void DmaController::write32(const uint32_t val)
1816
+{
1817
+	if(this->chan==0 && this->procnum==0)
1818
+	{
1819
+		//int zzz=9;
1820
+	}
1821
+	if(running)
1822
+	{
1823
+		//desp triggers this a lot. figure out whats going on
1824
+		//printf("thats weird..user edited dma control while it was running\n");
1825
+	}
1826
+	//printf("dma %d,%d WRITE %08X\n",procnum,chan,val);
1827
+	wordcount = val&0x1FFFFF;
1828
+	if(wordcount==0x9FbFC || wordcount == 0x1FFFFC || wordcount == 0x1EFFFC || wordcount == 0x1FFFFF) {
1829
+		//int zzz=9;
1830
+	}
1831
+	//uint8_t wasRepeatMode = repeatMode;
1832
+	uint8_t wasEnable = enable;
1833
+	uint32_t valhi = val>>16;
1834
+	dar = (EDMADestinationUpdate)((valhi>>5)&3);
1835
+	sar = (EDMASourceUpdate)((valhi>>7)&3);
1836
+	repeatMode = static_cast<uint8_t>(BIT9(valhi));
1837
+	bitWidth = (EDMABitWidth)BIT10(valhi);
1838
+	_startmode = (valhi>>11)&7;
1839
+	if(procnum==ARMCPU_ARM7) _startmode &= 6;
1840
+	irq = static_cast<uint8_t>(BIT14(valhi));
1841
+	enable = static_cast<uint8_t>(BIT15(valhi));
1842
+
1843
+	if(val==0x84400076 && saddr ==0x023BCEC4)
1844
+	{
1845
+		//int zzz=9;
1846
+	}
1847
+
1848
+	//if(irq) printf("!!!!!!!!!!!!IRQ!!!!!!!!!!!!!\n");
1849
+
1850
+	//make sure we don't get any old triggers
1851
+	if(!wasEnable && enable)
1852
+		triggered = false;
1853
+
1854
+	if(enable)
1855
+	{
1856
+		//address registers are reloaded from user's settings whenever dma is enabled
1857
+		//this is tested well by contra4 classic games, which use this to hdma scroll registers
1858
+		//specifically in the fit-screen mode.
1859
+		saddr = saddr_user;
1860
+		daddr = daddr_user;
1861
+	}
1862
+
1863
+	//printf("dma %d,%d set to startmode %d with wordcount set to: %08X\n",procnum,chan,_startmode,wordcount);
1864
+if(_startmode==0 && wordcount==1) {
1865
+	//int zzz=9;
1866
+}
1867
+	if(enable)
1868
+	{
1869
+		//int zzz=9;
1870
+	}
1871
+
1872
+	//analyze enabling and startmode.
1873
+	//note that we only do this if the dma was freshly enabled.
1874
+	//we should probably also only be latching these other regs in that case too..
1875
+	//but for now just this one will do (otherwise the dma repeat stop procedure (in this case the ff4 title menu load with gamecard dma) will fail)
1876
+	//if(!running) enable = userEnable;
1877
+
1878
+	//if we were previously in a triggered mode, and were already enabled,
1879
+	//then don't re-trigger now. this is rather confusing..
1880
+	//we really only want to auto-trigger gxfifo and immediate modes.
1881
+	//but we don't know what mode we're in yet.
1882
+	//so this is our workaround
1883
+	//(otherwise the dma repeat stop procedure (in this case the ff4 title menu load with gamecard dma) will fail)
1884
+	bool doNotStart = false;
1885
+	if(startmode != EDMAMode_Immediate/* && startmode != EDMAMode_GXFifo*/ && wasEnable) doNotStart = true;
1886
+
1887
+	//this dma may need to trigger now, so give it a chance
1888
+	//if(!(wasRepeatMode && !repeatMode)) //this was an older test
1889
+	if(!doNotStart)
1890
+		doSchedule();
1891
+
1892
+	//driver->DEBUG_UpdateIORegView(BaseDriver::EDEBUG_IOREG_DMA);
1893
+}
1894
+
1895
+void DmaController::exec()
1896
+{
1897
+	//this function runs when the DMA ends. the dma start actually queues this event after some kind of guess as to how long the DMA should take
1898
+
1899
+	//we'll need to unfreeze the arm9 bus now
1900
+	if(procnum==ARMCPU_ARM9) nds.freezeBus &= ~(1<<(chan+1));
1901
+
1902
+	dmaCheck = false;
1903
+
1904
+	if(running)
1905
+	{
1906
+		switch(startmode) {
1907
+			/*case EDMAMode_GXFifo:
1908
+				//this dma mode won't finish always its job when it gets signalled
1909
+				//sometimes it will have words left to transfer.
1910
+				//if(!paused) printf("gxfifo dma ended with %d remaining\n",wordcount); //only print this once
1911
+				if(wordcount>0) {
1912
+					doPause();
1913
+					break;
1914
+				}*/
1915
+			default:
1916
+				doStop();
1917
+				//driver->DEBUG_UpdateIORegView(BaseDriver::EDEBUG_IOREG_DMA);
1918
+				return;
1919
+		}
1920
+	}
1921
+
1922
+	if(enable)
1923
+	{
1924
+		//analyze startmode (this only gets latched when a dma begins)
1925
+		if(procnum==ARMCPU_ARM9) startmode = (EDMAMode)_startmode;
1926
+		else {
1927
+			//arm7 startmode analysis:
1928
+			static const EDMAMode lookup[] = {EDMAMode_Immediate,EDMAMode_VBlank,EDMAMode_Card,EDMAMode7_Wifi};
1929
+			//arm7 has a slightly different startmode encoding
1930
+			startmode = lookup[_startmode>>1];
1931
+			if(startmode == EDMAMode7_Wifi && (chan==1 || chan==3))
1932
+				startmode = EDMAMode7_GBASlot;
1933
+		}
1934
+
1935
+		//make it run, if it is triggered
1936
+		//but first, scan for triggering conditions
1937
+		switch(startmode) {
1938
+			case EDMAMode_Immediate:
1939
+				triggered = true;
1940
+				break;
1941
+			/*case EDMAMode_GXFifo:
1942
+				if(gxFIFO.size<=127)
1943
+					triggered = true;
1944
+				break;*/
1945
+			default:
1946
+				break;
1947
+		}
1948
+
1949
+		if(triggered)
1950
+		{
1951
+			//if(procnum==0) printf("vc=%03d %08lld trig type %d dma#%d w/words %d at src:%08X dst:%08X gxf:%d",nds.VCount,nds_timer,startmode,chan,wordcount,saddr,daddr,gxFIFO.size);
1952
+			if(saddr ==0x023BCCEC && wordcount==118) {
1953
+				//int zzz=9;
1954
+			}
1955
+			if(startmode==0 && daddr == 0x4000400) {
1956
+				//int zzz=9;
1957
+			}
1958
+			running = true;
1959
+			paused = false;
1960
+			if(procnum == ARMCPU_ARM9) doCopy<ARMCPU_ARM9>();
1961
+			else doCopy<ARMCPU_ARM7>();
1962
+			//printf(";%d\n",gxFIFO.size);
1963
+		}
1964
+	}
1965
+
1966
+	//driver->DEBUG_UpdateIORegView(BaseDriver::EDEBUG_IOREG_DMA);
1967
+}
1968
+
1969
+template<int PROCNUM>
1970
+void DmaController::doCopy()
1971
+{
1972
+	//generate a copy count depending on various copy mode's behavior
1973
+	uint32_t todo = wordcount;
1974
+	if(todo == 0) todo = 0x200000; //according to gbatek.. //TODO - this should not work this way for arm7 according to gbatek
1975
+	if(startmode == EDMAMode_MemDisplay)
1976
+	{
1977
+		todo = 128; //this is a hack. maybe an alright one though. it should be 4 words at a time. this is a whole scanline
1978
+
1979
+		//apparently this dma turns off after it finishes a frame
1980
+		if(nds.VCount==191) enable = 0;
1981
+	}
1982
+	if(startmode == EDMAMode_Card) todo *= 0x80;
1983
+	//if(startmode == EDMAMode_GXFifo) todo = std::min(todo,(uint32_t)112);
1984
+
1985
+	//determine how we're going to copy
1986
+	bool bogarted = false;
1987
+	uint32_t sz = (bitWidth==EDMABitWidth_16)?2:4;
1988
+	uint32_t dstinc = 0,srcinc;
1989
+	switch(dar) {
1990
+		case EDMADestinationUpdate_Increment       :  dstinc =  sz; break;
1991
+		case EDMADestinationUpdate_Decrement       :  dstinc = (uint32_t)-(int32_t)sz; break;
1992
+		case EDMADestinationUpdate_Fixed           :  dstinc =   0; break;
1993
+		case EDMADestinationUpdate_IncrementReload :  dstinc =  sz; break;
1994
+		default: bogarted = true; break;
1995
+	}
1996
+	switch(sar) {
1997
+		case EDMASourceUpdate_Increment : srcinc = sz; break;
1998
+		case EDMASourceUpdate_Decrement : srcinc = (uint32_t)-(int32_t)sz; break;
1999
+		case EDMASourceUpdate_Fixed		: srcinc = 0; break;
2000
+		case EDMASourceUpdate_Invalid   : bogarted = true; break;
2001
+		default: bogarted = true; break;
2002
+	}
2003
+
2004
+	//need to figure out what to do about this
2005
+	if(bogarted)
2006
+	{
2007
+		printf("YOUR GAME IS BOGARTED!!! PLEASE REPORT!!!\n");
2008
+		assert(false);
2009
+		return;
2010
+	}
2011
+
2012
+	uint32_t src = saddr;
2013
+	uint32_t dst = daddr;
2014
+
2015
+
2016
+	//if these do not use MMU_AT_DMA and the corresponding code in the read/write routines,
2017
+	//then danny phantom title screen will be filled with a garbage char which is made by
2018
+	//dmaing from 0x00000000 to 0x06000000
2019
+	//TODO - these might be losing out a lot by not going through the templated version anymore.
2020
+	//we might make another function to do just the raw copy op which can use them with checks
2021
+	//outside the loop
2022
+	int time_elapsed = 0;
2023
+	if(sz==4) {
2024
+		for(int32_t i=(int32_t)todo; i>0; i--)
2025
+		{
2026
+			time_elapsed += _MMU_accesstime<PROCNUM,MMU_AT_DMA,32,MMU_AD_READ,true>(src,true);
2027
+			time_elapsed += _MMU_accesstime<PROCNUM,MMU_AT_DMA,32,MMU_AD_WRITE,true>(dst,true);
2028
+			uint32_t temp = _MMU_read32(procnum,MMU_AT_DMA,src);
2029
+			_MMU_write32(procnum,MMU_AT_DMA,dst, temp);
2030
+			dst += dstinc;
2031
+			src += srcinc;
2032
+		}
2033
+	} else {
2034
+		for(int32_t i=(int32_t)todo; i>0; i--)
2035
+		{
2036
+			time_elapsed += _MMU_accesstime<PROCNUM,MMU_AT_DMA,16,MMU_AD_READ,true>(src,true);
2037
+			time_elapsed += _MMU_accesstime<PROCNUM,MMU_AT_DMA,16,MMU_AD_WRITE,true>(dst,true);
2038
+			uint16_t temp = _MMU_read16(procnum,MMU_AT_DMA,src);
2039
+			_MMU_write16(procnum,MMU_AT_DMA,dst, temp);
2040
+			dst += dstinc;
2041
+			src += srcinc;
2042
+		}
2043
+	}
2044
+
2045
+	//reschedule an event for the end of this dma, and figure out how much it cost us
2046
+	doSchedule();
2047
+
2048
+	// zeromus, check it
2049
+	if (wordcount > todo)
2050
+		nextEvent += todo/4; //TODO - surely this is a gross simplification
2051
+	//apparently moon has very, very tight timing (i didnt spy it using waitbyloop swi...)
2052
+	//so lets bump this down a bit for now,
2053
+	//(i think this code is in nintendo libraries)
2054
+
2055
+	//write back the addresses
2056
+	saddr = src;
2057
+	if(dar != EDMADestinationUpdate_IncrementReload) //but dont write back dst if we were supposed to reload
2058
+		daddr = dst;
2059
+
2060
+	//do wordcount accounting
2061
+	if(startmode == EDMAMode_Card)
2062
+		todo /= 0x80; //divide this funky one back down before subtracting it
2063
+
2064
+	if(!repeatMode)
2065
+		wordcount -= todo;
2066
+}
2067
+
2068
+void triggerDma(EDMAMode mode)
2069
+{
2070
+	MACRODO2(0, {
2071
+		const int i=X;
2072
+		MACRODO4(0, {
2073
+			const int j=X;
2074
+			MMU_new.dma[i][j].tryTrigger(mode);
2075
+		});
2076
+	});
2077
+}
2078
+
2079
+void DmaController::tryTrigger(EDMAMode mode)
2080
+{
2081
+	if(startmode != mode) return;
2082
+	if(!enable) return;
2083
+
2084
+	//hmm dont trigger it if its already running!
2085
+	//but paused things need triggers to continue
2086
+	if(running && !paused) return;
2087
+	triggered = true;
2088
+	doSchedule();
2089
+}
2090
+
2091
+void DmaController::doSchedule()
2092
+{
2093
+	dmaCheck = true;
2094
+	nextEvent = nds_timer;
2095
+	NDS_RescheduleDMA();
2096
+}
2097
+
2098
+
2099
+void DmaController::doPause()
2100
+{
2101
+	triggered = false;
2102
+	paused = true;
2103
+}
2104
+
2105
+void DmaController::doStop()
2106
+{
2107
+	//if(procnum==0) printf("%08lld stop type %d dma#%d\n",nds_timer,startmode,chan);
2108
+	running = false;
2109
+	if(!repeatMode) enable = false;
2110
+	if(irq) {
2111
+		NDS_makeIrq(procnum,IRQ_BIT_DMA_0+chan);
2112
+	}
2113
+}
2114
+
2115
+
2116
+
2117
+uint32_t DmaController::read32()
2118
+{
2119
+	uint32_t ret = 0;
2120
+	ret |= enable<<31;
2121
+	ret |= irq<<30;
2122
+	ret |= _startmode<<27;
2123
+	ret |= bitWidth<<26;
2124
+	ret |= repeatMode<<25;
2125
+	ret |= sar<<23;
2126
+	ret |= dar<<21;
2127
+	ret |= wordcount;
2128
+	//printf("dma %d,%d READ  %08X\n",procnum,chan,ret);
2129
+	if(ret == 0xAF000001) {
2130
+		//int zzz=9;
2131
+	}
2132
+	return ret;
2133
+}
2134
+
2135
+/*static inline void write_auxspicnt(const int, const int size, const int adr, const int val)
2136
+{
2137
+	//why val==0 to reset? is it a particular bit? its not bit 6...
2138
+	switch(size) {
2139
+		case 16:
2140
+			MMU.AUX_SPI_CNT = val;
2141
+			if (val == 0) MMU_new.backupDevice.reset_command();
2142
+			break;
2143
+		case 8:
2144
+			switch(adr) {
2145
+				case 0:
2146
+					T1WriteByte((uint8_t*)&MMU.AUX_SPI_CNT,0,val);
2147
+					if (val == 0) MMU_new.backupDevice.reset_command();
2148
+					break;
2149
+				case 1:
2150
+					T1WriteByte((uint8_t*)&MMU.AUX_SPI_CNT,1,val);
2151
+					break;
2152
+			}
2153
+	}
2154
+}*/
2155
+
2156
+
2157
+//================================================================================================== ARM9 *
2158
+//=========================================================================================================
2159
+//=========================================================================================================
2160
+//================================================= MMU write 08
2161
+void FASTCALL _MMU_ARM9_write08(uint32_t adr, uint8_t val)
2162
+{
2163
+	adr &= 0x0FFFFFFF;
2164
+
2165
+	//mmu_log_debug_ARM9(adr, "(write08) 0x%02X", val);
2166
+
2167
+	if(adr < 0x02000000)
2168
+	{
2169
+		T1WriteByte(MMU.ARM9_ITCM, adr&0x7FFF, val);
2170
+		return;
2171
+	}
2172
+
2173
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
2174
+	{
2175
+		//addon.write08(adr, val);
2176
+		return;
2177
+	}
2178
+
2179
+	//block 8bit writes to OAM and palette memory
2180
+	if((adr&0x0F000000)==0x07000000) return;
2181
+	if((adr&0x0F000000)==0x05000000) return;
2182
+
2183
+	if (adr >> 24 == 4)
2184
+	{
2185
+
2186
+		// TODO: add pal reg
2187
+		/*if (nds.power1.gpuMain == 0)
2188
+			if ((adr >= 0x04000008) && (adr<=0x0400005F)) return;*/
2189
+		/*if (nds.power1.gpuSub == 0)
2190
+			if ((adr >= 0x04001008) && (adr<=0x0400105F)) return;*/
2191
+		/*if (nds.power1.gfx3d_geometry == 0)
2192
+			if ((adr >= 0x04000400) && (adr<=0x040006FF)) return;
2193
+		if (nds.power1.gfx3d_render == 0)
2194
+			if ((adr >= 0x04000320) && (adr<=0x040003FF)) return;*/
2195
+
2196
+		if(MMU_new.is_dma(adr)) {
2197
+			MMU_new.write_dma(ARMCPU_ARM9,8,adr,val);
2198
+			return;
2199
+		}
2200
+
2201
+		switch(adr)
2202
+		{
2203
+			case REG_SQRTCNT: printf("ERROR 8bit SQRTCNT WRITE\n"); return;
2204
+			case REG_SQRTCNT+1: printf("ERROR 8bit SQRTCNT1 WRITE\n"); return;
2205
+			case REG_SQRTCNT+2: printf("ERROR 8bit SQRTCNT2 WRITE\n"); return;
2206
+			case REG_SQRTCNT+3: printf("ERROR 8bit SQRTCNT3 WRITE\n"); return;
2207
+
2208
+#if 1
2209
+			case REG_DIVCNT: printf("ERROR 8bit DIVCNT WRITE\n"); return;
2210
+			case REG_DIVCNT+1: printf("ERROR 8bit DIVCNT1 WRITE\n"); return;
2211
+			case REG_DIVCNT+2: printf("ERROR 8bit DIVCNT2 WRITE\n"); return;
2212
+			case REG_DIVCNT+3: printf("ERROR 8bit DIVCNT3 WRITE\n"); return;
2213
+#endif
2214
+
2215
+			//fog table: only write bottom 7 bits
2216
+			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x01: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x03:
2217
+			case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x05: case eng_3D_FOG_TABLE+0x06: case eng_3D_FOG_TABLE+0x07:
2218
+			case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x09: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0B:
2219
+			case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0D: case eng_3D_FOG_TABLE+0x0E: case eng_3D_FOG_TABLE+0x0F:
2220
+			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x11: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x13:
2221
+			case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x15: case eng_3D_FOG_TABLE+0x16: case eng_3D_FOG_TABLE+0x17:
2222
+			case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x19: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1B:
2223
+			case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1D: case eng_3D_FOG_TABLE+0x1E: case eng_3D_FOG_TABLE+0x1F:
2224
+				val &= 0x7F;
2225
+				break;*/
2226
+
2227
+			//ensata putchar port
2228
+			/*case 0x04FFF000:
2229
+				if(nds.ensataEmulation)
2230
+					printf("%c",val);
2231
+				break;
2232
+
2233
+			case eng_3D_GXSTAT:
2234
+				MMU_new.gxstat.write(8,adr,val);
2235
+				break;*/
2236
+
2237
+			/*case REG_DISPA_WIN0H:
2238
+				GPU_setWIN0_H1(MainScreen.gpu, val);
2239
+				break ;
2240
+			case REG_DISPA_WIN0H+1:
2241
+				GPU_setWIN0_H0 (MainScreen.gpu, val);
2242
+				break ;
2243
+			case REG_DISPA_WIN1H:
2244
+				GPU_setWIN1_H1 (MainScreen.gpu,val);
2245
+				break ;
2246
+			case REG_DISPA_WIN1H+1:
2247
+				GPU_setWIN1_H0 (MainScreen.gpu,val);
2248
+				break ; 	 */
2249
+
2250
+			/*case REG_DISPB_WIN0H:
2251
+				GPU_setWIN0_H1(SubScreen.gpu,val);
2252
+				break ;
2253
+			case REG_DISPB_WIN0H+1:
2254
+				GPU_setWIN0_H0(SubScreen.gpu,val);
2255
+				break ;
2256
+			case REG_DISPB_WIN1H:
2257
+				GPU_setWIN1_H1(SubScreen.gpu,val);
2258
+				break ;
2259
+			case REG_DISPB_WIN1H+1:
2260
+				GPU_setWIN1_H0(SubScreen.gpu,val);
2261
+				break ;*/
2262
+
2263
+			/*case REG_DISPA_WIN0V:
2264
+				GPU_setWIN0_V1(MainScreen.gpu,val) ;
2265
+				break ;
2266
+			case REG_DISPA_WIN0V+1:
2267
+				GPU_setWIN0_V0(MainScreen.gpu,val) ;
2268
+				break ;
2269
+			case REG_DISPA_WIN1V:
2270
+				GPU_setWIN1_V1(MainScreen.gpu,val) ;
2271
+				break ;
2272
+			case REG_DISPA_WIN1V+1:
2273
+				GPU_setWIN1_V0(MainScreen.gpu,val) ;
2274
+				break ; 	 */
2275
+
2276
+			/*case REG_DISPB_WIN0V:
2277
+				GPU_setWIN0_V1(SubScreen.gpu,val) ;
2278
+				break ;
2279
+			case REG_DISPB_WIN0V+1:
2280
+				GPU_setWIN0_V0(SubScreen.gpu,val) ;
2281
+				break ;
2282
+			case REG_DISPB_WIN1V:
2283
+				GPU_setWIN1_V1(SubScreen.gpu,val) ;
2284
+				break ;
2285
+			case REG_DISPB_WIN1V+1:
2286
+				GPU_setWIN1_V0(SubScreen.gpu,val) ;
2287
+				break ;*/
2288
+
2289
+			/*case REG_DISPA_WININ:
2290
+				GPU_setWININ0(MainScreen.gpu,val) ;
2291
+				break ;
2292
+			case REG_DISPA_WININ+1:
2293
+				GPU_setWININ1(MainScreen.gpu,val) ;
2294
+				break ;
2295
+			case REG_DISPA_WINOUT:
2296
+				GPU_setWINOUT(MainScreen.gpu,val) ;
2297
+				break ;
2298
+			case REG_DISPA_WINOUT+1:
2299
+				GPU_setWINOBJ(MainScreen.gpu,val);
2300
+				break ; 	 */
2301
+
2302
+			/*case REG_DISPB_WININ:
2303
+				GPU_setWININ0(SubScreen.gpu,val) ;
2304
+				break ;
2305
+			case REG_DISPB_WININ+1:
2306
+				GPU_setWININ1(SubScreen.gpu,val) ;
2307
+				break ;
2308
+			case REG_DISPB_WINOUT:
2309
+				GPU_setWINOUT(SubScreen.gpu,val) ;
2310
+				break ;
2311
+			case REG_DISPB_WINOUT+1:
2312
+				GPU_setWINOBJ(SubScreen.gpu,val) ;
2313
+				break ;*/
2314
+
2315
+			/*case REG_DISPA_BLDCNT:
2316
+				GPU_setBLDCNT_HIGH(MainScreen.gpu,val);
2317
+				break;
2318
+			case REG_DISPA_BLDCNT+1:
2319
+				GPU_setBLDCNT_LOW (MainScreen.gpu,val);
2320
+				break;*/
2321
+
2322
+			/*case REG_DISPB_BLDCNT:
2323
+				GPU_setBLDCNT_HIGH (SubScreen.gpu,val);
2324
+				break;
2325
+			case REG_DISPB_BLDCNT+1:
2326
+				GPU_setBLDCNT_LOW (SubScreen.gpu,val);
2327
+				break;*/
2328
+
2329
+			/*case REG_DISPA_BLDALPHA:
2330
+				MainScreen.gpu->setBLDALPHA_EVB(val);
2331
+				break;
2332
+			case REG_DISPA_BLDALPHA+1:
2333
+				MainScreen.gpu->setBLDALPHA_EVA(val);
2334
+				break;*/
2335
+
2336
+			/*case REG_DISPB_BLDALPHA:
2337
+				SubScreen.gpu->setBLDALPHA_EVB(val);
2338
+				break;
2339
+			case REG_DISPB_BLDALPHA+1:
2340
+				SubScreen.gpu->setBLDALPHA_EVA(val);
2341
+				break;*/
2342
+
2343
+			/*case REG_DISPA_BLDY:
2344
+				GPU_setBLDY_EVY(MainScreen.gpu,val) ;
2345
+				break ;
2346
+			case REG_DISPB_BLDY:
2347
+				GPU_setBLDY_EVY(SubScreen.gpu,val) ;
2348
+				break;*/
2349
+
2350
+			/*case REG_AUXSPICNT:
2351
+				write_auxspicnt(9,8,0,val);
2352
+				return;
2353
+			case REG_AUXSPICNT+1:
2354
+				write_auxspicnt(9,8,1,val);
2355
+				return;
2356
+
2357
+			case REG_AUXSPIDATA:
2358
+				if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF;
2359
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((uint8_t)val,ARMCPU_ARM9));
2360
+				MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag
2361
+				return;*/
2362
+
2363
+			case REG_WRAMCNT:
2364
+				/* Update WRAMSTAT at the ARM7 side */
2365
+				T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, val);
2366
+				break;
2367
+
2368
+            //case REG_POWCNT1: writereg_POWCNT1(8,adr,val); break;
2369
+
2370
+			//case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(8,adr,val); return;
2371
+			//case REG_DISPA_DISP3DCNT+1: writereg_DISP3DCNT(8,adr,val); return;
2372
+
2373
+			case REG_IF: REG_IF_WriteByte<ARMCPU_ARM9>(0,val); break;
2374
+			case REG_IF+1: REG_IF_WriteByte<ARMCPU_ARM9>(1,val); break;
2375
+			case REG_IF+2: REG_IF_WriteByte<ARMCPU_ARM9>(2,val); break;
2376
+			case REG_IF+3: REG_IF_WriteByte<ARMCPU_ARM9>(3,val); break;
2377
+
2378
+			/*case eng_3D_CLEAR_COLOR+0: case eng_3D_CLEAR_COLOR+1:
2379
+			case eng_3D_CLEAR_COLOR+2: case eng_3D_CLEAR_COLOR+3:
2380
+				//T1WriteByte((uint8_t*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val);
2381
+				break;*/
2382
+
2383
+			case REG_VRAMCNTA:
2384
+			case REG_VRAMCNTB:
2385
+			case REG_VRAMCNTC:
2386
+			case REG_VRAMCNTD:
2387
+			case REG_VRAMCNTE:
2388
+			case REG_VRAMCNTF:
2389
+			case REG_VRAMCNTG:
2390
+			case REG_VRAMCNTH:
2391
+			case REG_VRAMCNTI:
2392
+					MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val);
2393
+				break;
2394
+			/*case REG_DISPA_DISPMMEMFIFO:
2395
+			{
2396
+				DISP_FIFOsend(val);
2397
+				return;
2398
+			}*/
2399
+		#ifdef LOG_CARD
2400
+			case 0x040001A0 : /* TODO (clear): ??? */
2401
+			case 0x040001A1 :
2402
+			case 0x040001A2 :
2403
+			case 0x040001A8 :
2404
+			case 0x040001A9 :
2405
+			case 0x040001AA :
2406
+			case 0x040001AB :
2407
+			case 0x040001AC :
2408
+			case 0x040001AD :
2409
+			case 0x040001AE :
2410
+			case 0x040001AF :
2411
+						LOG("%08X : %02X\r\n", adr, val);
2412
+		#endif
2413
+
2414
+		}
2415
+
2416
+		MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val;
2417
+		return;
2418
+	}
2419
+
2420
+	//bool unmapped = false, restricted = false;
2421
+	//adr = MMU_LCDmap<ARMCPU_ARM9>(adr, unmapped, restricted);
2422
+	//if(unmapped) return;
2423
+	//if(restricted) return; //block 8bit vram writes
2424
+
2425
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
2426
+	MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val;
2427
+}
2428
+
2429
+//================================================= MMU ARM9 write 16
2430
+void FASTCALL _MMU_ARM9_write16(uint32_t adr, uint16_t val)
2431
+{
2432
+	adr &= 0x0FFFFFFE;
2433
+
2434
+	//mmu_log_debug_ARM9(adr, "(write16) 0x%04X", val);
2435
+
2436
+	if (adr < 0x02000000)
2437
+	{
2438
+		T1WriteWord(MMU.ARM9_ITCM, adr&0x7FFF, val);
2439
+		return;
2440
+	}
2441
+
2442
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
2443
+	{
2444
+		//addon.write16(adr, val);
2445
+		return;
2446
+	}
2447
+
2448
+	if((adr >> 24) == 4)
2449
+	{
2450
+		// TODO: add pal reg
2451
+		/*if (nds.power1.gpuMain == 0)
2452
+			if ((adr >= 0x04000008) && (adr<=0x0400005F)) return;*/
2453
+		/*if (nds.power1.gpuSub == 0)
2454
+			if ((adr >= 0x04001008) && (adr<=0x0400105F)) return;*/
2455
+		/*if (nds.power1.gfx3d_geometry == 0)
2456
+			if ((adr >= 0x04000400) && (adr<=0x040006FF)) return;
2457
+		if (nds.power1.gfx3d_render == 0)
2458
+			if ((adr >= 0x04000320) && (adr<=0x040003FF)) return;*/
2459
+
2460
+		if(MMU_new.is_dma(adr)) {
2461
+			if(val==0x02e9) {
2462
+				//int zzz=9;
2463
+			}
2464
+			MMU_new.write_dma(ARMCPU_ARM9,16,adr,val);
2465
+			return;
2466
+		}
2467
+
2468
+		switch (adr >> 4)
2469
+		{
2470
+						//toon table
2471
+			case 0x0400038:
2472
+			case 0x0400039:
2473
+			case 0x040003A:
2474
+			case 0x040003B:
2475
+				((uint16_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF)>>1] = val;
2476
+				//gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val);
2477
+			return;
2478
+		}
2479
+		// Address is an IO register
2480
+		switch(adr)
2481
+		{
2482
+		/*case eng_3D_GXSTAT:
2483
+			MMU_new.gxstat.write(16,adr,val);
2484
+			break;*/
2485
+
2486
+		//fog table: only write bottom 7 bits
2487
+		/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x06:
2488
+		case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0E:
2489
+		case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x16:
2490
+		case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1E:
2491
+			val &= 0x7F7F;
2492
+			break;*/
2493
+
2494
+		/*case REG_DISPA_BG2XL: MainScreen.gpu->setAffineStartWord(2,0,val,0); break;
2495
+		case REG_DISPA_BG2XH: MainScreen.gpu->setAffineStartWord(2,0,val,1); break;
2496
+		case REG_DISPA_BG2YL: MainScreen.gpu->setAffineStartWord(2,1,val,0); break;
2497
+		case REG_DISPA_BG2YH: MainScreen.gpu->setAffineStartWord(2,1,val,1); break;
2498
+		case REG_DISPA_BG3XL: MainScreen.gpu->setAffineStartWord(3,0,val,0); break;
2499
+		case REG_DISPA_BG3XH: MainScreen.gpu->setAffineStartWord(3,0,val,1); break;
2500
+		case REG_DISPA_BG3YL: MainScreen.gpu->setAffineStartWord(3,1,val,0); break;
2501
+		case REG_DISPA_BG3YH: MainScreen.gpu->setAffineStartWord(3,1,val,1); break;
2502
+		case REG_DISPB_BG2XL: SubScreen.gpu->setAffineStartWord(2,0,val,0); break;
2503
+		case REG_DISPB_BG2XH: SubScreen.gpu->setAffineStartWord(2,0,val,1); break;
2504
+		case REG_DISPB_BG2YL: SubScreen.gpu->setAffineStartWord(2,1,val,0); break;
2505
+		case REG_DISPB_BG2YH: SubScreen.gpu->setAffineStartWord(2,1,val,1); break;
2506
+		case REG_DISPB_BG3XL: SubScreen.gpu->setAffineStartWord(3,0,val,0); break;
2507
+		case REG_DISPB_BG3XH: SubScreen.gpu->setAffineStartWord(3,0,val,1); break;
2508
+		case REG_DISPB_BG3YL: SubScreen.gpu->setAffineStartWord(3,1,val,0); break;
2509
+		case REG_DISPB_BG3YH: SubScreen.gpu->setAffineStartWord(3,1,val,1); break;*/
2510
+
2511
+		//case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(16,adr,val); return;
2512
+
2513
+			// Alpha test reference value - Parameters:1
2514
+			/*case eng_3D_ALPHA_TEST_REF:
2515
+			{
2516
+				((uint16_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x340>>1] = val;
2517
+				//gfx3d_glAlphaFunc(val);
2518
+				return;
2519
+			}
2520
+
2521
+			case eng_3D_CLEAR_COLOR:
2522
+			case eng_3D_CLEAR_COLOR+2:
2523
+			{
2524
+				//T1WriteWord((uint8_t*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val);
2525
+				break;
2526
+			}
2527
+
2528
+			// Clear background depth setup - Parameters:2
2529
+			case eng_3D_CLEAR_DEPTH:
2530
+			{
2531
+				((uint16_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x354>>1] = val;
2532
+				//gfx3d_glClearDepth(val);
2533
+				return;
2534
+			}
2535
+			// Fog Color - Parameters:4b
2536
+			case eng_3D_FOG_COLOR:
2537
+			{
2538
+				((uint16_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x358>>1] = val;
2539
+				//gfx3d_glFogColor(val);
2540
+				return;
2541
+			}
2542
+			case eng_3D_FOG_OFFSET:
2543
+			{
2544
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x35C>>1] = val;
2545
+				//gfx3d_glFogOffset(val);
2546
+				return;
2547
+			}*/
2548
+
2549
+			case REG_DIVCNT:
2550
+				MMU_new.div.write16(val);
2551
+				execdiv();
2552
+				return;
2553
+#if 1
2554
+			case REG_DIVNUMER:
2555
+			case REG_DIVNUMER+2:
2556
+			case REG_DIVNUMER+4:
2557
+				printf("DIV: 16 write NUMER %08X. PLEASE REPORT! \n", val);
2558
+				break;
2559
+			case REG_DIVDENOM:
2560
+			case REG_DIVDENOM+2:
2561
+			case REG_DIVDENOM+4:
2562
+				printf("DIV: 16 write DENOM %08X. PLEASE REPORT! \n", val);
2563
+				break;
2564
+#endif
2565
+			case REG_SQRTCNT:
2566
+				MMU_new.sqrt.write16(val);
2567
+				execsqrt();
2568
+				return;
2569
+
2570
+			/*case REG_DISPA_BLDCNT:
2571
+				GPU_setBLDCNT(MainScreen.gpu,val) ;
2572
+				break ;
2573
+			case REG_DISPB_BLDCNT:
2574
+				GPU_setBLDCNT(SubScreen.gpu,val) ;
2575
+				break ;
2576
+			case REG_DISPA_BLDALPHA:
2577
+				MainScreen.gpu->setBLDALPHA(val);
2578
+				break ;
2579
+			case REG_DISPB_BLDALPHA:
2580
+				SubScreen.gpu->setBLDALPHA(val);
2581
+				break ;
2582
+			case REG_DISPA_BLDY:
2583
+				GPU_setBLDY_EVY(MainScreen.gpu,val) ;
2584
+				break ;
2585
+			case REG_DISPB_BLDY:
2586
+				GPU_setBLDY_EVY(SubScreen.gpu,val) ;
2587
+				break;
2588
+			case REG_DISPA_MASTERBRIGHT:
2589
+				GPU_setMasterBrightness (MainScreen.gpu, val);
2590
+				break;*/
2591
+				/*
2592
+			case REG_DISPA_MOSAIC:
2593
+				GPU_setMOSAIC(MainScreen.gpu,val) ;
2594
+				break ;
2595
+			case REG_DISPB_MOSAIC:
2596
+				GPU_setMOSAIC(SubScreen.gpu,val) ;
2597
+				break ;
2598
+				*/
2599
+			//case REG_DISPA_BG0HOFS:
2600
+			//	GPU_setBGxHOFS(0, MainScreen.gpu, val);
2601
+			//	break;
2602
+			//case REG_DISPA_BG0VOFS:
2603
+			//	GPU_setBGxVOFS(0, MainScreen.gpu, val);
2604
+			//	break;
2605
+			//case REG_DISPA_BG1HOFS:
2606
+			//	GPU_setBGxHOFS(1, MainScreen.gpu, val);
2607
+			//	break;
2608
+			//case REG_DISPA_BG1VOFS:
2609
+			//	GPU_setBGxVOFS(1, MainScreen.gpu, val);
2610
+			//	break;
2611
+			//case REG_DISPA_BG2HOFS:
2612
+			//	GPU_setBGxHOFS(2, MainScreen.gpu, val);
2613
+			//	break;
2614
+			//case REG_DISPA_BG2VOFS:
2615
+			//	GPU_setBGxVOFS(2, MainScreen.gpu, val);
2616
+			//	break;
2617
+			//case REG_DISPA_BG3HOFS:
2618
+			//	GPU_setBGxHOFS(3, MainScreen.gpu, val);
2619
+			//	break;
2620
+			//case REG_DISPA_BG3VOFS:
2621
+			//	GPU_setBGxVOFS(3, MainScreen.gpu, val);
2622
+			//	break;
2623
+
2624
+			/*case REG_DISPA_WIN0H:
2625
+				GPU_setWIN0_H (MainScreen.gpu,val) ;
2626
+				break ;
2627
+			case REG_DISPA_WIN1H:
2628
+				GPU_setWIN1_H(MainScreen.gpu,val) ;
2629
+				break ;
2630
+			case REG_DISPB_WIN0H:
2631
+				GPU_setWIN0_H(SubScreen.gpu,val) ;
2632
+				break ;
2633
+			case REG_DISPB_WIN1H:
2634
+				GPU_setWIN1_H(SubScreen.gpu,val) ;
2635
+				break ;
2636
+			case REG_DISPA_WIN0V:
2637
+				GPU_setWIN0_V(MainScreen.gpu,val) ;
2638
+				break ;
2639
+			case REG_DISPA_WIN1V:
2640
+				GPU_setWIN1_V(MainScreen.gpu,val) ;
2641
+				break ;
2642
+			case REG_DISPB_WIN0V:
2643
+				GPU_setWIN0_V(SubScreen.gpu,val) ;
2644
+				break ;
2645
+			case REG_DISPB_WIN1V:
2646
+				GPU_setWIN1_V(SubScreen.gpu,val) ;
2647
+				break ;
2648
+			case REG_DISPA_WININ:
2649
+				GPU_setWININ(MainScreen.gpu, val) ;
2650
+				break ;
2651
+			case REG_DISPA_WINOUT:
2652
+				GPU_setWINOUT16(MainScreen.gpu, val) ;
2653
+				break ; 	 */
2654
+
2655
+		/*	case REG_DISPB_BG0HOFS:
2656
+				GPU_setBGxHOFS(0, SubScreen.gpu, val);
2657
+				break;
2658
+			case REG_DISPB_BG0VOFS:
2659
+				GPU_setBGxVOFS(0, SubScreen.gpu, val);
2660
+				break;
2661
+			case REG_DISPB_BG1HOFS:
2662
+				GPU_setBGxHOFS(1, SubScreen.gpu, val);
2663
+				break;
2664
+			case REG_DISPB_BG1VOFS:
2665
+				GPU_setBGxVOFS(1, SubScreen.gpu, val);
2666
+				break;
2667
+			case REG_DISPB_BG2HOFS:
2668
+				GPU_setBGxHOFS(2, SubScreen.gpu, val);
2669
+				break;
2670
+			case REG_DISPB_BG2VOFS:
2671
+				GPU_setBGxVOFS(2, SubScreen.gpu, val);
2672
+				break;
2673
+			case REG_DISPB_BG3HOFS:
2674
+				GPU_setBGxHOFS(3, SubScreen.gpu, val);
2675
+				break;
2676
+			case REG_DISPB_BG3VOFS:
2677
+				GPU_setBGxVOFS(3, SubScreen.gpu, val);
2678
+				break;*/
2679
+
2680
+			/*case REG_DISPB_WININ:
2681
+				GPU_setWININ(SubScreen.gpu, val) ;
2682
+				break ;
2683
+			case REG_DISPB_WINOUT:
2684
+				GPU_setWINOUT16(SubScreen.gpu, val) ;
2685
+				break ;*/
2686
+
2687
+			/*case REG_DISPB_MASTERBRIGHT:
2688
+				GPU_setMasterBrightness (SubScreen.gpu, val);
2689
+				break;*/
2690
+
2691
+            /*case REG_POWCNT1:
2692
+				writereg_POWCNT1(16,adr,val);
2693
+				return;*/
2694
+
2695
+			case REG_EXMEMCNT:
2696
+			{
2697
+				uint16_t remote_proc = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204);
2698
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204, val);
2699
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204, (val & 0xFF80) | (remote_proc & 0x7F));
2700
+				return;
2701
+			}
2702
+
2703
+			/*case REG_AUXSPICNT:
2704
+				write_auxspicnt(9,16,0,val);
2705
+				return;
2706
+
2707
+			case REG_AUXSPIDATA:
2708
+				if(val!=0)
2709
+				   MMU.AUX_SPI_CMD = val & 0xFF;
2710
+
2711
+				//T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val));
2712
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((uint8_t)val,ARMCPU_ARM9));
2713
+				MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag
2714
+				return;*/
2715
+
2716
+			/*case REG_DISPA_BG0CNT :
2717
+				//GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val);
2718
+				//GPU_setBGProp(MainScreen.gpu, 0, val);
2719
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x8, val);
2720
+				return;
2721
+			case REG_DISPA_BG1CNT :
2722
+				//GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val);
2723
+				//GPU_setBGProp(MainScreen.gpu, 1, val);
2724
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xA, val);
2725
+				return;
2726
+			case REG_DISPA_BG2CNT :
2727
+				//GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val);
2728
+				//GPU_setBGProp(MainScreen.gpu, 2, val);
2729
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC, val);
2730
+				return;
2731
+			case REG_DISPA_BG3CNT :
2732
+				//GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val);
2733
+				//GPU_setBGProp(MainScreen.gpu, 3, val);
2734
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xE, val);
2735
+				return;
2736
+			case REG_DISPB_BG0CNT :
2737
+				//GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val);
2738
+				//GPU_setBGProp(SubScreen.gpu, 0, val);
2739
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1008, val);
2740
+				return;
2741
+			case REG_DISPB_BG1CNT :
2742
+				//GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val);
2743
+				//GPU_setBGProp(SubScreen.gpu, 1, val);
2744
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100A, val);
2745
+				return;
2746
+			case REG_DISPB_BG2CNT :
2747
+				//GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val);
2748
+				//GPU_setBGProp(SubScreen.gpu, 2, val);
2749
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100C, val);
2750
+				return;
2751
+			case REG_DISPB_BG3CNT :
2752
+				//GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val);
2753
+				//GPU_setBGProp(SubScreen.gpu, 3, val);
2754
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x100E, val);
2755
+				return;*/
2756
+
2757
+			case REG_VRAMCNTA:
2758
+			case REG_VRAMCNTC:
2759
+			case REG_VRAMCNTE:
2760
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
2761
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), val >> 8);
2762
+				break;
2763
+			case REG_VRAMCNTG:
2764
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
2765
+				/* Update WRAMSTAT at the ARM7 side */
2766
+				T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, val >> 8);
2767
+				break;
2768
+			case REG_VRAMCNTH:
2769
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
2770
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), val >> 8);
2771
+				break;
2772
+
2773
+			case REG_IME:
2774
+				NDS_Reschedule();
2775
+				MMU.reg_IME[ARMCPU_ARM9] = val & 0x01;
2776
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x208, val);
2777
+				return;
2778
+			case REG_IE :
2779
+				NDS_Reschedule();
2780
+				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF0000) | val;
2781
+				return;
2782
+			case REG_IE + 2 :
2783
+				NDS_Reschedule();
2784
+				MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF) | (((uint32_t)val)<<16);
2785
+				return;
2786
+			case REG_IF: REG_IF_WriteWord<ARMCPU_ARM9>(0,val); return;
2787
+			case REG_IF+2: REG_IF_WriteWord<ARMCPU_ARM9>(2,val); return;
2788
+
2789
+            case REG_IPCSYNC :
2790
+					MMU_IPCSync(ARMCPU_ARM9, val);
2791
+				return;
2792
+
2793
+			case REG_IPCFIFOCNT :
2794
+					IPC_FIFOcnt(ARMCPU_ARM9, val);
2795
+				return;
2796
+            case REG_TM0CNTL :
2797
+            case REG_TM1CNTL :
2798
+            case REG_TM2CNTL :
2799
+            case REG_TM3CNTL :
2800
+				MMU.timerReload[ARMCPU_ARM9][(adr>>2)&3] = val;
2801
+				return;
2802
+			case REG_TM0CNTH :
2803
+			case REG_TM1CNTH :
2804
+			case REG_TM2CNTH :
2805
+			case REG_TM3CNTH :
2806
+			{
2807
+				int timerIndex	= ((adr-2)>>2)&0x3;
2808
+				write_timer(ARMCPU_ARM9, timerIndex, val);
2809
+				return;
2810
+			}
2811
+
2812
+			/*case REG_DISPA_DISPCNT :
2813
+				{
2814
+					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0) & 0xFFFF0000) | val;
2815
+					//GPU_setVideoProp(MainScreen.gpu, v);
2816
+					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, v);
2817
+					return;
2818
+				}
2819
+			case REG_DISPA_DISPCNT+2 :
2820
+				{
2821
+					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0) & 0xFFFF) | ((uint32_t) val << 16);
2822
+					//GPU_setVideoProp(MainScreen.gpu, v);
2823
+					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, v);
2824
+				}
2825
+				return;
2826
+			case REG_DISPA_DISPCAPCNT :
2827
+				{
2828
+					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64) & 0xFFFF0000) | val;
2829
+					//GPU_set_DISPCAPCNT(v);
2830
+					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64, v);
2831
+					return;
2832
+				}
2833
+			case REG_DISPA_DISPCAPCNT + 2:
2834
+				{
2835
+					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64) & 0xFFFF) | ((uint32_t)val << 16);
2836
+					//GPU_set_DISPCAPCNT(v);
2837
+					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x64, v);
2838
+					return;
2839
+				}
2840
+
2841
+			case REG_DISPB_DISPCNT :
2842
+				{
2843
+					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000) & 0xFFFF0000) | val;
2844
+					//GPU_setVideoProp(SubScreen.gpu, v);
2845
+					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, v);
2846
+					return;
2847
+				}
2848
+			case REG_DISPB_DISPCNT+2 :
2849
+				{
2850
+					//emu_halt();
2851
+					uint32_t v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000) & 0xFFFF) | ((uint32_t) val << 16);
2852
+					//GPU_setVideoProp(SubScreen.gpu, v);
2853
+					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, v);
2854
+					return;
2855
+				}*/
2856
+
2857
+			/*case REG_DISPA_DISPMMEMFIFO:
2858
+			{
2859
+				DISP_FIFOsend(val);
2860
+				return;
2861
+			}*/
2862
+
2863
+			case REG_GCROMCTRL :
2864
+				MMU_writeToGCControl<ARMCPU_ARM9>( (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF0000) | val);
2865
+				return;
2866
+			case REG_GCROMCTRL+2 :
2867
+				MMU_writeToGCControl<ARMCPU_ARM9>( (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0xFFFF) | ((uint32_t) val << 16));
2868
+				return;
2869
+		}
2870
+
2871
+		T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
2872
+		return;
2873
+	}
2874
+
2875
+
2876
+	bool unmapped, restricted;
2877
+	adr = MMU_LCDmap/*<ARMCPU_ARM9>*/(adr, unmapped, restricted);
2878
+	if(unmapped) return;
2879
+
2880
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
2881
+	T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
2882
+}
2883
+
2884
+//================================================= MMU ARM9 write 32
2885
+void FASTCALL _MMU_ARM9_write32(uint32_t adr, uint32_t val)
2886
+{
2887
+	adr &= 0x0FFFFFFC;
2888
+
2889
+	//mmu_log_debug_ARM9(adr, "(write32) 0x%08X", val);
2890
+
2891
+	if(adr<0x02000000)
2892
+	{
2893
+		T1WriteLong(MMU.ARM9_ITCM, adr&0x7FFF, val);
2894
+		return ;
2895
+	}
2896
+
2897
+
2898
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
2899
+	{
2900
+		//addon.write32(adr, val);
2901
+		return;
2902
+	}
2903
+
2904
+	if((adr&0x0F000000)==0x05000000)
2905
+	{
2906
+		//int zzz=9;
2907
+	}
2908
+
2909
+#if 0
2910
+	if ((adr & 0xFF800000) == 0x04800000) {
2911
+		// access to non regular hw registers
2912
+		// return to not overwrite valid data
2913
+		return ;
2914
+	}
2915
+#endif
2916
+
2917
+	if((adr>>24)==4)
2918
+	{
2919
+		// TODO: add pal reg
2920
+		/*if (nds.power1.gpuMain == 0)
2921
+			if ((adr >= 0x04000008) && (adr<=0x0400005F)) return;*/
2922
+		/*if (nds.power1.gpuSub == 0)
2923
+			if ((adr >= 0x04001008) && (adr<=0x0400105F)) return;*/
2924
+		/*if (nds.power1.gfx3d_geometry == 0)
2925
+			if ((adr >= 0x04000400) && (adr<=0x040006FF)) return;
2926
+		if (nds.power1.gfx3d_render == 0)
2927
+			if ((adr >= 0x04000320) && (adr<=0x040003FF)) return;*/
2928
+
2929
+		// MightyMax: no need to do several ifs, when only one can happen
2930
+		// switch/case instead
2931
+		// both comparison >=,< per if can be replaced by one bit comparison since
2932
+		// they are 2^4 aligned and 2^4n wide
2933
+		// this looks ugly but should reduce load on register writes, they are done as
2934
+		// lookups by the compiler
2935
+		/*switch (adr >> 4)
2936
+		{
2937
+			case 0x400033:		//edge color table
2938
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val;
2939
+				return;
2940
+
2941
+			case 0x400038:
2942
+			case 0x400039:
2943
+			case 0x40003A:
2944
+			case 0x40003B:		//toon table
2945
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val;
2946
+				//gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val);
2947
+				return;
2948
+
2949
+			case 0x400040:
2950
+			case 0x400041:
2951
+			case 0x400042:
2952
+			case 0x400043:		// FIFO Commands
2953
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val;
2954
+				//gfx3d_sendCommandToFIFO(val);
2955
+				return;
2956
+
2957
+			case 0x400044:
2958
+			case 0x400045:
2959
+			case 0x400046:
2960
+			case 0x400047:
2961
+			case 0x400048:
2962
+			case 0x400049:
2963
+			case 0x40004A:
2964
+			case 0x40004B:
2965
+			case 0x40004C:
2966
+			case 0x40004D:
2967
+			case 0x40004E:
2968
+			case 0x40004F:
2969
+			case 0x400050:
2970
+			case 0x400051:
2971
+			case 0x400052:
2972
+			case 0x400053:
2973
+			case 0x400054:
2974
+			case 0x400055:
2975
+			case 0x400056:
2976
+			case 0x400057:
2977
+			case 0x400058:
2978
+			case 0x400059:
2979
+			case 0x40005A:
2980
+			case 0x40005B:
2981
+			case 0x40005C:		// Individual Commands
2982
+				if (gxFIFO.size > 254)
2983
+					nds.freezeBus = true;
2984
+
2985
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val;
2986
+				//gfx3d_sendCommand(adr, val);
2987
+				return;
2988
+
2989
+			default:
2990
+				break;
2991
+		}*/
2992
+
2993
+		if(MMU_new.is_dma(adr)) {
2994
+			MMU_new.write_dma(ARMCPU_ARM9,32,adr,val);
2995
+			return;
2996
+		}
2997
+
2998
+		switch(adr)
2999
+		{
3000
+			case REG_SQRTCNT: MMU_new.sqrt.write16((uint16_t)val); return;
3001
+			case REG_DIVCNT: MMU_new.div.write16((uint16_t)val); return;
3002
+
3003
+			//case REG_POWCNT1: writereg_POWCNT1(32,adr,val); break;
3004
+
3005
+			//fog table: only write bottom 7 bits
3006
+			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0C:
3007
+			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1C:
3008
+				val &= 0x7F7F7F7F;
3009
+				break;*/
3010
+
3011
+
3012
+			//ensata handshaking port?
3013
+			/*case 0x04FFF010:
3014
+				if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_ack && val == 0x13579bdf)
3015
+					nds.ensataHandshake = ENSATA_HANDSHAKE_confirm;
3016
+				if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_confirm && val == 0xfdb97531)
3017
+				{
3018
+					printf("ENSATA HANDSHAKE COMPLETE\n");
3019
+					nds.ensataHandshake = ENSATA_HANDSHAKE_complete;
3020
+				}
3021
+				break;*/
3022
+
3023
+			//todo - these are usually write only regs (these and 1000 more)
3024
+			//shouldnt we block them from getting written? ugh
3025
+			/*case eng_3D_CLIPMTX_RESULT:
3026
+				if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_none && val==0x2468ace0)
3027
+				{
3028
+					printf("ENSATA HANDSHAKE BEGIN\n");
3029
+					nds.ensataHandshake = ENSATA_HANDSHAKE_query;
3030
+				}
3031
+				break;
3032
+
3033
+			case eng_3D_GXSTAT:
3034
+				MMU_new.gxstat.write32(val);
3035
+				break;*/
3036
+			/*case REG_DISPA_BG2XL:
3037
+				MainScreen.gpu->setAffineStart(2,0,val);
3038
+				return;
3039
+			case REG_DISPA_BG2YL:
3040
+				MainScreen.gpu->setAffineStart(2,1,val);
3041
+				return;
3042
+			case REG_DISPB_BG2XL:
3043
+				SubScreen.gpu->setAffineStart(2,0,val);
3044
+				return;
3045
+			case REG_DISPB_BG2YL:
3046
+				SubScreen.gpu->setAffineStart(2,1,val);
3047
+				return;
3048
+			case REG_DISPA_BG3XL:
3049
+				MainScreen.gpu->setAffineStart(3,0,val);
3050
+				return;
3051
+			case REG_DISPA_BG3YL:
3052
+				MainScreen.gpu->setAffineStart(3,1,val);
3053
+				return;
3054
+			case REG_DISPB_BG3XL:
3055
+				SubScreen.gpu->setAffineStart(3,0,val);
3056
+				return;
3057
+			case REG_DISPB_BG3YL:
3058
+				SubScreen.gpu->setAffineStart(3,1,val);
3059
+				return;*/
3060
+
3061
+			// Alpha test reference value - Parameters:1
3062
+			/*case eng_3D_ALPHA_TEST_REF:
3063
+			{
3064
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x340>>2] = val;
3065
+				//gfx3d_glAlphaFunc(val);
3066
+				return;
3067
+			}
3068
+
3069
+			case eng_3D_CLEAR_COLOR:
3070
+				//T1WriteLong((uint8_t*)&gfx3d.state.clearColor,0,val);
3071
+				break;
3072
+
3073
+			// Clear background depth setup - Parameters:2
3074
+			case eng_3D_CLEAR_DEPTH:
3075
+			{
3076
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x354>>2] = val;
3077
+				//gfx3d_glClearDepth(val);
3078
+				return;
3079
+			}
3080
+			// Fog Color - Parameters:4b
3081
+			case 0x04000358:
3082
+			{
3083
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x358>>2] = val;
3084
+				//gfx3d_glFogColor(val);
3085
+				return;
3086
+			}
3087
+			case 0x0400035C:
3088
+			{
3089
+				((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x35C>>2] = val;
3090
+				//gfx3d_glFogOffset(val);
3091
+				return;
3092
+			}*/
3093
+
3094
+			//case REG_DISPA_BG0HOFS:
3095
+			//	GPU_setBGxHOFS(0, MainScreen.gpu, val&0xFFFF);
3096
+			//	GPU_setBGxVOFS(0, MainScreen.gpu, (val>>16));
3097
+			//	break;
3098
+
3099
+			/*case REG_DISPA_WININ:
3100
+			{
3101
+				GPU_setWININ(MainScreen.gpu, val & 0xFFFF) ;
3102
+				GPU_setWINOUT16(MainScreen.gpu, (val >> 16) & 0xFFFF) ;
3103
+	            break;
3104
+			}
3105
+			case REG_DISPB_WININ:
3106
+			{
3107
+				GPU_setWININ(SubScreen.gpu, val & 0xFFFF) ;
3108
+				GPU_setWINOUT16(SubScreen.gpu, (val >> 16) & 0xFFFF) ;
3109
+	            break;
3110
+			}*/
3111
+
3112
+			/*case REG_DISPA_WIN0H:
3113
+			{
3114
+				GPU_setWIN0_H(MainScreen.gpu, val&0xFFFF);
3115
+				GPU_setWIN1_H(MainScreen.gpu, val>>16);
3116
+				break;
3117
+			}
3118
+			case REG_DISPA_WIN0V:
3119
+			{
3120
+				GPU_setWIN0_V(MainScreen.gpu, val&0xFFFF);
3121
+				GPU_setWIN1_V(MainScreen.gpu, val>>16);
3122
+				break;
3123
+			}
3124
+			case REG_DISPB_WIN0H:
3125
+			{
3126
+				GPU_setWIN0_H(SubScreen.gpu, val&0xFFFF);
3127
+				GPU_setWIN1_H(SubScreen.gpu, val>>16);
3128
+				break;
3129
+			}
3130
+			case REG_DISPB_WIN0V:
3131
+			{
3132
+				GPU_setWIN0_V(SubScreen.gpu, val&0xFFFF);
3133
+				GPU_setWIN1_V(SubScreen.gpu, val>>16);
3134
+				break;
3135
+			}*/
3136
+
3137
+			/*case REG_DISPA_MASTERBRIGHT:
3138
+				GPU_setMasterBrightness(MainScreen.gpu, val & 0xFFFF);
3139
+				break;
3140
+			case REG_DISPB_MASTERBRIGHT:
3141
+				GPU_setMasterBrightness(SubScreen.gpu, val & 0xFFFF);
3142
+				break;*/
3143
+
3144
+			/*case REG_DISPA_BLDCNT:
3145
+			{
3146
+				GPU_setBLDCNT   (MainScreen.gpu,val&0xffff);
3147
+				MainScreen.gpu->setBLDALPHA(val>>16);
3148
+				break;
3149
+			}
3150
+			case REG_DISPB_BLDCNT:
3151
+			{
3152
+				GPU_setBLDCNT   (SubScreen.gpu,val&0xffff);
3153
+				SubScreen.gpu->setBLDALPHA(val>>16);
3154
+				break;
3155
+			}*/
3156
+
3157
+			/*case REG_DISPA_BLDY:
3158
+				GPU_setBLDY_EVY(MainScreen.gpu,val&0xFFFF) ;
3159
+				break ;
3160
+			case REG_DISPB_BLDY:
3161
+				GPU_setBLDY_EVY(SubScreen.gpu,val&0xFFFF);
3162
+				break;*/
3163
+
3164
+			/*case REG_DISPA_DISPCNT :
3165
+				//GPU_setVideoProp(MainScreen.gpu, val);
3166
+				//GPULOG("MAIN INIT 32B %08X\r\n", val);
3167
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0, val);
3168
+				return;
3169
+
3170
+			case REG_DISPB_DISPCNT :
3171
+				//GPU_setVideoProp(SubScreen.gpu, val);
3172
+				//GPULOG("SUB INIT 32B %08X\r\n", val);
3173
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, val);
3174
+				return;*/
3175
+
3176
+			case REG_VRAMCNTA:
3177
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
3178
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), (val >> 8) & 0xFF);
3179
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+2), (val >> 16) & 0xFF);
3180
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+3), (val >> 24) & 0xFF);
3181
+				break;
3182
+			case REG_VRAMCNTE:
3183
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
3184
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), (val >> 8) & 0xFF);
3185
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+2), (val >> 16) & 0xFF);
3186
+				/* Update WRAMSTAT at the ARM7 side */
3187
+				T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, (val >> 24) & 0xFF);
3188
+				break;
3189
+			case REG_VRAMCNTH:
3190
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA), val & 0xFF);
3191
+				MMU_VRAMmapControl(static_cast<uint8_t>(adr-REG_VRAMCNTA+1), (val >> 8) & 0xFF);
3192
+				break;
3193
+
3194
+			case REG_IME :
3195
+				NDS_Reschedule();
3196
+				MMU.reg_IME[ARMCPU_ARM9] = val & 0x01;
3197
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x208, val);
3198
+				return;
3199
+
3200
+			case REG_IE :
3201
+				NDS_Reschedule();
3202
+				MMU.reg_IE[ARMCPU_ARM9] = val;
3203
+				return;
3204
+
3205
+			case REG_IF: REG_IF_WriteLong<ARMCPU_ARM9>(val); return;
3206
+
3207
+            case REG_TM0CNTL:
3208
+            case REG_TM1CNTL:
3209
+            case REG_TM2CNTL:
3210
+            case REG_TM3CNTL:
3211
+			{
3212
+				int timerIndex = (adr>>2)&0x3;
3213
+				MMU.timerReload[ARMCPU_ARM9][timerIndex] = (uint16_t)val;
3214
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & 0xFFF, static_cast<uint16_t>(val));
3215
+				write_timer(ARMCPU_ARM9, timerIndex, val>>16);
3216
+				return;
3217
+			}
3218
+
3219
+			case REG_DIVNUMER:
3220
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290, val);
3221
+				execdiv();
3222
+				return;
3223
+			case REG_DIVNUMER+4:
3224
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x294, val);
3225
+				execdiv();
3226
+				return;
3227
+
3228
+            case REG_DIVDENOM :
3229
+				{
3230
+					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298, val);
3231
+					execdiv();
3232
+					return;
3233
+				}
3234
+			case REG_DIVDENOM+4 :
3235
+				{
3236
+					T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x29C, val);
3237
+					execdiv();
3238
+					return;
3239
+				}
3240
+
3241
+			case REG_SQRTPARAM :
3242
+			{
3243
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B8, val);
3244
+				execsqrt();
3245
+				return;
3246
+			}
3247
+			case REG_SQRTPARAM+4 :
3248
+			{
3249
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2BC, val);
3250
+				execsqrt();
3251
+				return;
3252
+			}
3253
+
3254
+			case REG_IPCSYNC:
3255
+				MMU_IPCSync(ARMCPU_ARM9, val);
3256
+				return;
3257
+			case REG_IPCFIFOCNT:
3258
+				IPC_FIFOcnt(ARMCPU_ARM9, static_cast<uint16_t>(val));
3259
+				return;
3260
+			case REG_IPCFIFOSEND:
3261
+				IPC_FIFOsend(ARMCPU_ARM9, val);
3262
+				return;
3263
+
3264
+
3265
+			case REG_GCROMCTRL :
3266
+				MMU_writeToGCControl<ARMCPU_ARM9>(val);
3267
+				return;
3268
+			case REG_DISPA_DISPCAPCNT :
3269
+				//INFO("MMU write32: REG_DISPA_DISPCAPCNT 0x%X\n", val);
3270
+				//GPU_set_DISPCAPCNT(val);
3271
+				T1WriteLong(MMU.ARM9_REG, 0x64, val);
3272
+				return;
3273
+
3274
+			/*case REG_DISPA_BG0CNT :
3275
+				//GPU_setBGProp(MainScreen.gpu, 0, (val&0xFFFF));
3276
+				//GPU_setBGProp(MainScreen.gpu, 1, (val>>16));
3277
+				//if((val>>16)==0x400) emu_halt();
3278
+				T1WriteLong(MMU.ARM9_REG, 8, val);
3279
+				return;
3280
+			case REG_DISPA_BG2CNT :
3281
+					//GPU_setBGProp(MainScreen.gpu, 2, (val&0xFFFF));
3282
+					//GPU_setBGProp(MainScreen.gpu, 3, (val>>16));
3283
+					T1WriteLong(MMU.ARM9_REG, 0xC, val);
3284
+				return;
3285
+			case REG_DISPB_BG0CNT :
3286
+					//GPU_setBGProp(SubScreen.gpu, 0, (val&0xFFFF));
3287
+					//GPU_setBGProp(SubScreen.gpu, 1, (val>>16));
3288
+					T1WriteLong(MMU.ARM9_REG, 0x1008, val);
3289
+				return;
3290
+			case REG_DISPB_BG2CNT :
3291
+					//GPU_setBGProp(SubScreen.gpu, 2, (val&0xFFFF));
3292
+					//GPU_setBGProp(SubScreen.gpu, 3, (val>>16));
3293
+					T1WriteLong(MMU.ARM9_REG, 0x100C, val);
3294
+				return;*/
3295
+			/*case REG_DISPA_DISPMMEMFIFO:
3296
+			{
3297
+				DISP_FIFOsend(val);
3298
+				return;
3299
+			}*/
3300
+
3301
+			//case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(32,adr,val); return;
3302
+
3303
+			case REG_GCDATAIN:
3304
+				slot1_device.write32(ARMCPU_ARM9, REG_GCDATAIN,val);
3305
+				return;
3306
+		}
3307
+
3308
+		T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
3309
+		return;
3310
+	}
3311
+
3312
+	bool unmapped, restricted;
3313
+	adr = MMU_LCDmap/*<ARMCPU_ARM9>*/(adr, unmapped, restricted);
3314
+	if(unmapped) return;
3315
+
3316
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
3317
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
3318
+}
3319
+
3320
+//================================================= MMU ARM9 read 08
3321
+uint8_t FASTCALL _MMU_ARM9_read08(uint32_t adr)
3322
+{
3323
+	adr &= 0x0FFFFFFF;
3324
+
3325
+	//mmu_log_debug_ARM9(adr, "(read08) 0x%02X", MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]]);
3326
+
3327
+	if(adr<0x02000000)
3328
+		return T1ReadByte(MMU.ARM9_ITCM, adr&0x7FFF);
3329
+
3330
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3331
+		return 0/*addon.read08(adr)*/;
3332
+
3333
+	if (adr >> 24 == 4)
3334
+	{	//Address is an IO register
3335
+
3336
+		if(MMU_new.is_dma(adr)) return static_cast<uint8_t>(MMU_new.read_dma(ARMCPU_ARM9,8,adr));
3337
+
3338
+		switch(adr)
3339
+		{
3340
+			case REG_IF: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>());
3341
+			case REG_IF+1: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>()>>8);
3342
+			case REG_IF+2: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>()>>16);
3343
+			case REG_IF+3: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM9>()>>24);
3344
+
3345
+			/*case REG_DISPA_DISPSTAT:
3346
+				break;
3347
+			case REG_DISPA_DISPSTAT+1:
3348
+				break;
3349
+			case REG_DISPx_VCOUNT: return nds.VCount & 0xFF;
3350
+			case REG_DISPx_VCOUNT+1: return (nds.VCount>>8) & 0xFF;*/
3351
+#if 0
3352
+			case REG_SQRTCNT: printf("ERROR 8bit SQRTCNT READ\n"); return 0;
3353
+			case REG_SQRTCNT+1: printf("ERROR 8bit SQRTCNT1 READ\n"); return 0;//(MMU_new.sqrt.read16() & 0xFF00)>>8;
3354
+#else
3355
+			case REG_SQRTCNT: return MMU_new.sqrt.read16() & 0xFF;
3356
+			case REG_SQRTCNT+1: return (MMU_new.sqrt.read16()>>8) & 0xFF;
3357
+#endif
3358
+			case REG_SQRTCNT+2: printf("ERROR 8bit SQRTCNT2 READ\n"); return 0;
3359
+			case REG_SQRTCNT+3: printf("ERROR 8bit SQRTCNT3 READ\n"); return 0;
3360
+#if 1
3361
+			case REG_DIVCNT: printf("ERROR 8bit DIVCNT READ\n"); return 0;
3362
+			case REG_DIVCNT+1: printf("ERROR 8bit DIVCNT1 READ\n"); return 0;
3363
+#else
3364
+			case REG_DIVCNT: return MMU_new.div.read16() & 0xFF;
3365
+			case REG_DIVCNT+1: return (MMU_new.div.read16()>>8) & 0xFF;
3366
+#endif
3367
+			case REG_DIVCNT+2: printf("ERROR 8bit DIVCNT2 READ\n"); return 0;
3368
+			case REG_DIVCNT+3: printf("ERROR 8bit DIVCNT3 READ\n"); return 0;
3369
+
3370
+			//fog table: write only
3371
+			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x01: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x03:
3372
+			case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x05: case eng_3D_FOG_TABLE+0x06: case eng_3D_FOG_TABLE+0x07:
3373
+			case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x09: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0B:
3374
+			case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0D: case eng_3D_FOG_TABLE+0x0E: case eng_3D_FOG_TABLE+0x0F:
3375
+			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x11: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x13:
3376
+			case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x15: case eng_3D_FOG_TABLE+0x16: case eng_3D_FOG_TABLE+0x17:
3377
+			case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x19: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1B:
3378
+			case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1D: case eng_3D_FOG_TABLE+0x1E: case eng_3D_FOG_TABLE+0x1F:
3379
+				return 0;*/
3380
+
3381
+			/*case REG_POWCNT1:
3382
+			case REG_POWCNT1+1:
3383
+			case REG_POWCNT1+2:
3384
+			case REG_POWCNT1+3:
3385
+				return readreg_POWCNT1(8,adr);*/
3386
+
3387
+			/*case eng_3D_GXSTAT:
3388
+				return MMU_new.gxstat.read(8,adr);*/
3389
+
3390
+			//case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(8,adr);
3391
+			//case REG_DISPA_DISP3DCNT+1: return readreg_DISP3DCNT(8,adr);
3392
+			//case REG_DISPA_DISP3DCNT+2: return readreg_DISP3DCNT(8,adr);
3393
+			//case REG_DISPA_DISP3DCNT+3: return readreg_DISP3DCNT(8,adr);
3394
+		}
3395
+	}
3396
+
3397
+	bool unmapped, restricted;
3398
+	adr = MMU_LCDmap/*<ARMCPU_ARM9>*/(adr, unmapped, restricted);
3399
+	if(unmapped) return 0;
3400
+
3401
+	return MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]];
3402
+}
3403
+
3404
+//================================================= MMU ARM9 read 16
3405
+uint16_t FASTCALL _MMU_ARM9_read16(uint32_t adr)
3406
+{
3407
+	adr &= 0x0FFFFFFE;
3408
+
3409
+	//mmu_log_debug_ARM9(adr, "(read16) 0x%04X", T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]));
3410
+
3411
+	if(adr<0x02000000)
3412
+		return T1ReadWord_guaranteedAligned(MMU.ARM9_ITCM, adr & 0x7FFE);
3413
+
3414
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3415
+		return 0/*addon.read16(adr)*/;
3416
+
3417
+	if (adr >> 24 == 4)
3418
+	{
3419
+		if(MMU_new.is_dma(adr)) return static_cast<uint16_t>(MMU_new.read_dma(ARMCPU_ARM9,16,adr));
3420
+
3421
+		// Address is an IO register
3422
+		switch(adr)
3423
+		{
3424
+			/*case REG_DISPA_DISPSTAT:
3425
+				break;*/
3426
+
3427
+			case REG_SQRTCNT: return MMU_new.sqrt.read16();
3428
+			case REG_DIVCNT: return MMU_new.div.read16();
3429
+			//case eng_3D_GXSTAT: return MMU_new.gxstat.read(16,adr);
3430
+
3431
+			/*case REG_DISPA_VCOUNT:
3432
+				if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_query)
3433
+				{
3434
+					nds.ensataHandshake = ENSATA_HANDSHAKE_ack;
3435
+					return 270;
3436
+				} else return nds.VCount;
3437
+
3438
+			// ============================================= 3D
3439
+			case eng_3D_RAM_COUNT:
3440
+				return 0;
3441
+				//almost worthless for now
3442
+				//return gfx3d_GetNumPolys();
3443
+			case eng_3D_RAM_COUNT+2:
3444
+				return 0;
3445
+				//almost worthless for now
3446
+				//return gfx3d_GetNumVertex();*/
3447
+			// ============================================= 3D end
3448
+			case REG_IME :
3449
+				return (uint16_t)MMU.reg_IME[ARMCPU_ARM9];
3450
+
3451
+			case REG_IE :
3452
+				return (uint16_t)MMU.reg_IE[ARMCPU_ARM9];
3453
+			case REG_IE + 2 :
3454
+				return (uint16_t)(MMU.reg_IE[ARMCPU_ARM9]>>16);
3455
+
3456
+			case REG_IF: return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM9>());
3457
+			case REG_IF+2: return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM9>()>>16);
3458
+
3459
+			case REG_TM0CNTL :
3460
+			case REG_TM1CNTL :
3461
+			case REG_TM2CNTL :
3462
+			case REG_TM3CNTL :
3463
+				return read_timer(ARMCPU_ARM9,(adr&0xF)>>2);
3464
+
3465
+			case REG_AUXSPICNT:
3466
+				return MMU.AUX_SPI_CNT;
3467
+
3468
+            /*case REG_POWCNT1:
3469
+			case REG_POWCNT1+2:
3470
+				return readreg_POWCNT1(16,adr);*/
3471
+
3472
+			//case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(16,adr);
3473
+			//case REG_DISPA_DISP3DCNT+2: return readreg_DISP3DCNT(16,adr);
3474
+
3475
+			/*case 0x04000130:
3476
+			case 0x04000136:
3477
+				//not sure whether these should trigger from byte reads
3478
+				LagFrameFlag=0;
3479
+				break;*/
3480
+
3481
+			//fog table: write only
3482
+			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x06:
3483
+			case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0E:
3484
+			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x16:
3485
+			case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1E:
3486
+				return 0;*/
3487
+		}
3488
+
3489
+		return  T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
3490
+	}
3491
+
3492
+	//bool unmapped = false/*, restricted*/;
3493
+	//adr = MMU_LCDmap<ARMCPU_ARM9>(adr,unmapped, restricted);
3494
+	//if(unmapped) return 0;
3495
+
3496
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF
3497
+	return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr >> 20]);
3498
+}
3499
+
3500
+//================================================= MMU ARM9 read 32
3501
+uint32_t FASTCALL _MMU_ARM9_read32(uint32_t adr)
3502
+{
3503
+	adr &= 0x0FFFFFFC;
3504
+
3505
+	//mmu_log_debug_ARM9(adr, "(read32) 0x%08X", T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]));
3506
+
3507
+	if(adr<0x02000000)
3508
+		return T1ReadLong_guaranteedAligned(MMU.ARM9_ITCM, adr&0x7FFC);
3509
+
3510
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3511
+		return 0/*addon.read32(adr)*/;
3512
+
3513
+	// Address is an IO register
3514
+	if((adr >> 24) == 4)
3515
+	{
3516
+		if(MMU_new.is_dma(adr)) return MMU_new.read_dma(ARMCPU_ARM9,32,adr);
3517
+
3518
+		switch(adr)
3519
+		{
3520
+			case REG_DSIMODE:
3521
+				if(!nds.Is_DSI()) break;
3522
+				return 1;
3523
+			case 0x04004008:
3524
+				if(!nds.Is_DSI()) break;
3525
+				return 0x8000;
3526
+
3527
+			/*case REG_DISPA_DISPSTAT:
3528
+				break;
3529
+
3530
+			case REG_DISPx_VCOUNT: return nds.VCount;*/
3531
+
3532
+			//Dolphin Island Underwater Adventures uses this amidst seemingly reasonable divs so we're going to emulate it.
3533
+			case REG_DIVCNT: return MMU_new.div.read16();
3534
+			//I guess we'll do this also
3535
+			case REG_SQRTCNT: return MMU_new.sqrt.read16();
3536
+
3537
+			//fog table: write only
3538
+			/*case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0C:
3539
+			case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1C:
3540
+				return 0;*/
3541
+
3542
+			/*case eng_3D_CLIPMTX_RESULT:
3543
+			case eng_3D_CLIPMTX_RESULT+4:
3544
+			case eng_3D_CLIPMTX_RESULT+8:
3545
+			case eng_3D_CLIPMTX_RESULT+12:
3546
+			case eng_3D_CLIPMTX_RESULT+16:
3547
+			case eng_3D_CLIPMTX_RESULT+20:
3548
+			case eng_3D_CLIPMTX_RESULT+24:
3549
+			case eng_3D_CLIPMTX_RESULT+28:
3550
+			case eng_3D_CLIPMTX_RESULT+32:
3551
+			case eng_3D_CLIPMTX_RESULT+36:
3552
+			case eng_3D_CLIPMTX_RESULT+40:
3553
+			case eng_3D_CLIPMTX_RESULT+44:
3554
+			case eng_3D_CLIPMTX_RESULT+48:
3555
+			case eng_3D_CLIPMTX_RESULT+52:
3556
+			case eng_3D_CLIPMTX_RESULT+56:
3557
+			case eng_3D_CLIPMTX_RESULT+60:
3558
+			{
3559
+				//LOG("4000640h..67Fh - CLIPMTX_RESULT - Read Current Clip Coordinates Matrix (R)");
3560
+				return gfx3d_GetClipMatrix ((adr-0x04000640)/4);
3561
+			}*/
3562
+			/*case eng_3D_VECMTX_RESULT:
3563
+			case eng_3D_VECMTX_RESULT+4:
3564
+			case eng_3D_VECMTX_RESULT+8:
3565
+			case eng_3D_VECMTX_RESULT+12:
3566
+			case eng_3D_VECMTX_RESULT+16:
3567
+			case eng_3D_VECMTX_RESULT+20:
3568
+			case eng_3D_VECMTX_RESULT+24:
3569
+			case eng_3D_VECMTX_RESULT+28:
3570
+			case eng_3D_VECMTX_RESULT+32:
3571
+			{
3572
+				//LOG("4000680h..6A3h - VECMTX_RESULT - Read Current Directional Vector Matrix (R)");
3573
+				return gfx3d_GetDirectionalMatrix ((adr-0x04000680)/4);
3574
+			}*/
3575
+
3576
+			/*case eng_3D_RAM_COUNT:
3577
+			{
3578
+				return gfx3d_GetNumPolys() | ((gfx3d_GetNumVertex()) << 16);
3579
+				//LOG ("read32 - RAM_COUNT -> 0x%X", ((uint32_t *)(MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF])>>2]);
3580
+			}*/
3581
+
3582
+			/*case eng_3D_POS_RESULT:
3583
+			case eng_3D_POS_RESULT+4:
3584
+			case eng_3D_POS_RESULT+8:
3585
+			case eng_3D_POS_RESULT+12:
3586
+			{
3587
+				return gfx3d_glGetPosRes((adr & 0xF) >> 2);
3588
+			}*/
3589
+			/*case eng_3D_GXSTAT:
3590
+				return MMU_new.gxstat.read(32,adr);*/
3591
+			//	======================================== 3D end
3592
+
3593
+
3594
+			case REG_IME :
3595
+				return MMU.reg_IME[ARMCPU_ARM9];
3596
+			case REG_IE :
3597
+				return MMU.reg_IE[ARMCPU_ARM9];
3598
+
3599
+			case REG_IF: return MMU.gen_IF<ARMCPU_ARM9>();
3600
+
3601
+			case REG_IPCFIFORECV :
3602
+				return IPC_FIFOrecv(ARMCPU_ARM9);
3603
+			case REG_TM0CNTL :
3604
+			case REG_TM1CNTL :
3605
+			case REG_TM2CNTL :
3606
+			case REG_TM3CNTL :
3607
+				{
3608
+					uint32_t val = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], (adr + 2) & 0xFFF);
3609
+					return MMU.timer[ARMCPU_ARM9][(adr&0xF)>>2] | (val<<16);
3610
+				}
3611
+
3612
+			case REG_GCDATAIN: return MMU_readFromGC<ARMCPU_ARM9>();
3613
+            //case REG_POWCNT1: return readreg_POWCNT1(32,adr);
3614
+			//case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(32,adr);
3615
+		}
3616
+		return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
3617
+	}
3618
+
3619
+	//bool unmapped = false/*, restricted*/;
3620
+	//adr = MMU_LCDmap<ARMCPU_ARM9>(adr,unmapped, restricted);
3621
+	//if(unmapped) return 0;
3622
+
3623
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [zeromus, inspired by shash]
3624
+	return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
3625
+}
3626
+//================================================================================================== ARM7 *
3627
+//=========================================================================================================
3628
+//=========================================================================================================
3629
+//================================================= MMU ARM7 write 08
3630
+void FASTCALL _MMU_ARM7_write08(uint32_t adr, uint8_t val)
3631
+{
3632
+	adr &= 0x0FFFFFFF;
3633
+
3634
+	//mmu_log_debug_ARM7(adr, "(write08) 0x%02X", val);
3635
+
3636
+	if (adr < 0x4000) return;	// PU BIOS
3637
+
3638
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3639
+	{
3640
+		//addon.write08(adr, val);
3641
+		return;
3642
+	}
3643
+
3644
+	if ((adr>=0x04000400)&&(adr<0x04000520))
3645
+	{
3646
+		SPU_WriteByte(adr, val);
3647
+		return;
3648
+    }
3649
+
3650
+	if ((adr & 0xFFFF0000) == 0x04800000)
3651
+	{
3652
+		/* is wifi hardware, dont intermix with regular hardware registers */
3653
+		// 8-bit writes to wifi I/O and RAM are ignored
3654
+		// Reference: http://nocash.emubase.de/gbatek.htm#dswifiiomap
3655
+		return;
3656
+	}
3657
+
3658
+	if (adr >> 24 == 4)
3659
+	{
3660
+		if(MMU_new.is_dma(adr)) { MMU_new.write_dma(ARMCPU_ARM7,8,adr,val); return; }
3661
+
3662
+		switch(adr)
3663
+		{
3664
+			case REG_IF: REG_IF_WriteByte<ARMCPU_ARM7>(0,val); break;
3665
+			case REG_IF+1: REG_IF_WriteByte<ARMCPU_ARM7>(1,val); break;
3666
+			case REG_IF+2: REG_IF_WriteByte<ARMCPU_ARM7>(2,val); break;
3667
+			case REG_IF+3: REG_IF_WriteByte<ARMCPU_ARM7>(3,val); break;
3668
+
3669
+			case REG_POSTFLG:
3670
+				// hack for patched firmwares
3671
+				if (val == 1)
3672
+				{
3673
+					if (_MMU_ARM7_read08(REG_POSTFLG) != 0)
3674
+						break;
3675
+					_MMU_write32<ARMCPU_ARM9>(0x27FFE24, gameInfo.header.ARM9exe);
3676
+					_MMU_write32<ARMCPU_ARM7>(0x27FFE34, gameInfo.header.ARM7exe);
3677
+				}
3678
+				break;
3679
+
3680
+			case REG_HALTCNT:
3681
+				//printf("halt 0x%02X\n", val);
3682
+				switch(val)
3683
+				{
3684
+					case 0xC0: NDS_Sleep(); break;
3685
+					case 0x80: armcpu_Wait4IRQ(&NDS_ARM7); break;
3686
+					default: break;
3687
+				}
3688
+				break;
3689
+
3690
+			/*case REG_RTC:
3691
+				rtcWrite(val);
3692
+				return;*/
3693
+
3694
+			/*case REG_AUXSPICNT:
3695
+				write_auxspicnt(9,8,0,val);
3696
+				return;
3697
+			case REG_AUXSPICNT+1:
3698
+				write_auxspicnt(9,8,1,val);
3699
+				return;
3700
+			case REG_AUXSPIDATA:
3701
+				if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF;
3702
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((uint8_t)val,ARMCPU_ARM7));
3703
+				MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag
3704
+				return;*/
3705
+		}
3706
+		MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]]=val;
3707
+		return;
3708
+	}
3709
+
3710
+	//bool unmapped = false/*, restricted*/;
3711
+	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
3712
+	//if(unmapped) return;
3713
+
3714
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
3715
+	MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]]=val;
3716
+}
3717
+
3718
+//================================================= MMU ARM7 write 16
3719
+void FASTCALL _MMU_ARM7_write16(uint32_t adr, uint16_t val)
3720
+{
3721
+	adr &= 0x0FFFFFFE;
3722
+
3723
+	//mmu_log_debug_ARM7(adr, "(write16) 0x%04X", val);
3724
+
3725
+	if (adr < 0x4000) return;	// PU BIOS
3726
+
3727
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
3728
+	{
3729
+		//addon.write16(adr, val);
3730
+		return;
3731
+	}
3732
+
3733
+	//wifi mac access
3734
+	/*if ((adr & 0xFFFF0000) == 0x04800000)
3735
+	{
3736
+		WIFI_write16(adr,val);
3737
+		T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x48], adr&MMU.MMU_MASK[ARMCPU_ARM7][0x48], val);
3738
+		return;
3739
+	}*/
3740
+
3741
+	if ((adr>=0x04000400)&&(adr<0x04000520))
3742
+	{
3743
+		SPU_WriteWord(adr, val);
3744
+		return;
3745
+	}
3746
+
3747
+	if((adr >> 24) == 4)
3748
+	{
3749
+		if(MMU_new.is_dma(adr)) { MMU_new.write_dma(ARMCPU_ARM7,16,adr,val); return; }
3750
+
3751
+		//Address is an IO register
3752
+		switch(adr)
3753
+		{
3754
+			case REG_DISPA_VCOUNT:
3755
+				if (nds.VCount >= 202 && nds.VCount <= 212)
3756
+				{
3757
+					printf("VCOUNT set to %i (previous value %i)\n", val, nds.VCount);
3758
+					nds.VCount = val;
3759
+				}
3760
+				else
3761
+					printf("Attempt to set VCOUNT while not within 202-212 (%i), ignored\n", nds.VCount);
3762
+				return;
3763
+
3764
+			/*case REG_RTC:
3765
+				rtcWrite(val);
3766
+				break;*/
3767
+
3768
+			case REG_EXMEMCNT:
3769
+			{
3770
+				uint16_t remote_proc = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204);
3771
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204, (val & 0x7F) | (remote_proc & 0xFF80));
3772
+			}
3773
+			return;
3774
+
3775
+			/*case REG_EXTKEYIN: //readonly
3776
+				return;*/
3777
+
3778
+
3779
+			/*case REG_POWCNT2:
3780
+				{
3781
+					nds.power2.speakers = BIT0(val);
3782
+					nds.power2.wifi = BIT0(val);
3783
+				}
3784
+				return;*/
3785
+
3786
+
3787
+			/*case REG_AUXSPICNT:
3788
+				write_auxspicnt(7,16,0,val);
3789
+			return;
3790
+
3791
+			case REG_AUXSPIDATA:
3792
+				if(val!=0)
3793
+				   MMU.AUX_SPI_CMD = val & 0xFF;
3794
+
3795
+				//T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val));
3796
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((uint8_t)val,ARMCPU_ARM7));
3797
+				MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag
3798
+			return;*/
3799
+
3800
+			case REG_SPICNT :
3801
+				{
3802
+					int reset_firmware = 1;
3803
+
3804
+					if ( ((MMU.SPI_CNT >> 8) & 0x3) == 1)
3805
+					{
3806
+						if ( ((val >> 8) & 0x3) == 1)
3807
+						{
3808
+							if ( BIT11(MMU.SPI_CNT))
3809
+							{
3810
+								// select held
3811
+								reset_firmware = 0;
3812
+							}
3813
+						}
3814
+					}
3815
+
3816
+						//MMU.fw.com == 0; // reset fw device communication
3817
+					if ( reset_firmware)
3818
+					{
3819
+					  // reset fw device communication
3820
+					  fw_reset_com(&MMU.fw);
3821
+					}
3822
+					MMU.SPI_CNT = val;
3823
+
3824
+					T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff, val);
3825
+				}
3826
+				return;
3827
+
3828
+			case REG_SPIDATA :
3829
+				{
3830
+					uint16_t spicnt;
3831
+
3832
+					if(val!=0)
3833
+						MMU.SPI_CMD = val;
3834
+
3835
+					spicnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff);
3836
+
3837
+					switch((spicnt >> 8) & 0x3)
3838
+					{
3839
+						case 0 :
3840
+							{
3841
+								if(!MMU.powerMan_CntRegWritten)
3842
+								{
3843
+									MMU.powerMan_CntReg = (val & 0xFF);
3844
+									MMU.powerMan_CntRegWritten = true;
3845
+								}
3846
+								else
3847
+								{
3848
+									uint16_t reg = MMU.powerMan_CntReg&0x7F;
3849
+									reg &= 0x7;
3850
+									if(reg==5 || reg==6 || reg==7) reg = 4;
3851
+
3852
+									//(let's start with emulating a DS lite, since it is the more complex case)
3853
+									if(MMU.powerMan_CntReg & 0x80)
3854
+									{
3855
+										//read
3856
+										val = MMU.powerMan_Reg[reg];
3857
+									}
3858
+									else
3859
+									{
3860
+										//write
3861
+										MMU.powerMan_Reg[reg] = (uint8_t)val;
3862
+
3863
+										//enum PM_Bits //from libnds
3864
+										//{
3865
+											//PM_SOUND_AMP		= BIT(0) ,   /*!< \brief Power the sound hardware (needed to hear stuff in GBA mode too) */
3866
+											//PM_SOUND_MUTE		= BIT(1),    /*!< \brief   Mute the main speakers, headphone output will still work. */
3867
+											//PM_BACKLIGHT_BOTTOM	= BIT(2),    /*!< \brief   Enable the top backlight if set */
3868
+											//PM_BACKLIGHT_TOP	= BIT(3)  ,  /*!< \brief   Enable the bottom backlight if set */
3869
+											static const uint32_t PM_SYSTEM_PWR = BIT(6);   /*!< \brief  Turn the power *off* if set */
3870
+										//};
3871
+
3872
+										//our totally pathetic register handling, only the one thing we've wanted so far
3873
+										if(MMU.powerMan_Reg[0]&PM_SYSTEM_PWR) {
3874
+											printf("SYSTEM POWERED OFF VIA ARM7 SPI POWER DEVICE\n");
3875
+											//emu_halt();
3876
+											execute = false;
3877
+										}
3878
+									}
3879
+
3880
+									MMU.powerMan_CntRegWritten = false;
3881
+								}
3882
+							}
3883
+						break;
3884
+
3885
+						case 1 : /* firmware memory device */
3886
+							if((spicnt & 0x3) != 0)      /* check SPI baudrate (must be 4mhz) */
3887
+							{
3888
+								T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, 0);
3889
+								break;
3890
+							}
3891
+							T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, (uint8_t)val));
3892
+						return;
3893
+
3894
+						case 2:
3895
+						{
3896
+							if(nds.Is_DSI())
3897
+							{
3898
+								//pass data to TSC
3899
+								val = MMU_new.dsi_tsc.write16(val);
3900
+
3901
+								//apply reset command if appropriate
3902
+								if(!BIT11(MMU.SPI_CNT))
3903
+									MMU_new.dsi_tsc.reset_command();
3904
+
3905
+								break;
3906
+							}
3907
+
3908
+							int channel = (MMU.SPI_CMD&0x70)>>4;
3909
+							//printf("%08X\n",channel);
3910
+							switch(channel)
3911
+							{
3912
+								case TSC_MEASURE_TEMP1:
3913
+									if(spicnt & 0x800)
3914
+									{
3915
+										if(partie)
3916
+										{
3917
+											val = ((716<<3)&0x7FF);
3918
+											partie = 0;
3919
+											break;
3920
+										}
3921
+										val = (716>>5);
3922
+										partie = 1;
3923
+										break;
3924
+									}
3925
+									val = ((716<<3)&0x7FF);
3926
+									partie = 1;
3927
+									break;
3928
+								case TSC_MEASURE_TEMP2:
3929
+									if(spicnt & 0x800)
3930
+									{
3931
+										if(partie)
3932
+										{
3933
+											val = ((865<<3)&0x7FF);
3934
+											partie = 0;
3935
+											break;
3936
+										}
3937
+										val = (865>>5);
3938
+										partie = 1;
3939
+										break;
3940
+									}
3941
+									val = ((865<<3)&0x7FF);
3942
+									partie = 1;
3943
+									break;
3944
+
3945
+								case TSC_MEASURE_Y:
3946
+									{
3947
+										//counter the number of adc touch coord reads and jitter it after a while to simulate a shaky human hand or multiple reads
3948
+										/*nds.adc_jitterctr++;
3949
+										if(nds.adc_jitterctr == 25)
3950
+										{
3951
+											nds.adc_jitterctr = 0;
3952
+											nds.adc_touchY ^= 16;
3953
+											nds.adc_touchX ^= 16;
3954
+										}*/
3955
+										if(MMU.SPI_CNT&(1<<11))
3956
+										{
3957
+											if(partie)
3958
+											{
3959
+												//val = (nds.adc_touchY<<3) & 0xFF;
3960
+												partie = 0;
3961
+												break;
3962
+											}
3963
+
3964
+											//val = (nds.adc_touchY>>5) & 0xFF;
3965
+											partie = 1;
3966
+											break;
3967
+										}
3968
+										//val = (nds.adc_touchY<<3)&0xFF;
3969
+										partie = 1;
3970
+										break;
3971
+									}
3972
+								case TSC_MEASURE_Z1: //Z1
3973
+									//used for pressure calculation - must be nonzero or else some softwares will think the stylus is up.
3974
+									//something is wrong in here and some of these LSB dont make it back to libnds... whatever.
3975
+									/*{
3976
+										u16 scratch;
3977
+										CalculateTouchPressure(CommonSettings.StylusPressure,val,scratch);
3978
+									}*/
3979
+									if(spicnt & 0x800)
3980
+									{
3981
+										if(partie)
3982
+										{
3983
+											val = ((val<<3)&0x7FF);
3984
+											partie = 0;
3985
+											break;
3986
+										}
3987
+										val = (val>>5);
3988
+										partie = 1;
3989
+										break;
3990
+									}
3991
+									val = ((val<<3)&0x7FF);
3992
+									partie = 1;
3993
+									break;
3994
+								case TSC_MEASURE_Z2: //Z2
3995
+									//used for pressure calculation - must be nonzero or else some softwares will think the stylus is up.
3996
+									//something is wrong in here and some of these LSB dont make it back to libnds... whatever.
3997
+									/*{
3998
+										u16 scratch;
3999
+										CalculateTouchPressure(CommonSettings.StylusPressure,scratch,val);
4000
+									}*/
4001
+									if(spicnt & 0x800)
4002
+									{
4003
+										if(partie)
4004
+										{
4005
+											val = ((val<<3)&0x7FF);
4006
+											partie = 0;
4007
+											break;
4008
+										}
4009
+										val = (val>>5);
4010
+										partie = 1;
4011
+										break;
4012
+									}
4013
+									val = ((val<<3)&0x7FF);
4014
+									partie = 1;
4015
+									break;
4016
+								case TSC_MEASURE_X:
4017
+									if(spicnt & 0x800)
4018
+									{
4019
+										if(partie)
4020
+										{
4021
+											//val = (nds.adc_touchX << 3) & 0xFF;
4022
+											partie = 0;
4023
+											break;
4024
+										}
4025
+										//val = (nds.adc_touchX>>5) & 0xFF;
4026
+										partie = 1;
4027
+										break;
4028
+									}
4029
+									//val = (nds.adc_touchX<<3) & 0xFF;
4030
+									partie = 1;
4031
+									break;
4032
+								case TSC_MEASURE_AUX:
4033
+									/*if(!(val & 0x80))
4034
+										val = (Mic_ReadSample() & 0xFF);
4035
+									else*/
4036
+										val = 0;
4037
+									break;
4038
+							}
4039
+							break;
4040
+						}
4041
+
4042
+						case 3 :
4043
+						/* NOTICE: Device 3 of SPI is reserved (unused and unusable) */
4044
+						break;
4045
+					}
4046
+				}
4047
+
4048
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, val);
4049
+				return;
4050
+
4051
+				/* NOTICE: Perhaps we have to use gbatek-like reg names instead of libnds-like ones ...*/
4052
+
4053
+			case REG_IME :
4054
+				NDS_Reschedule();
4055
+				MMU.reg_IME[ARMCPU_ARM7] = val & 0x01;
4056
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x208, val);
4057
+				return;
4058
+			case REG_IE :
4059
+				NDS_Reschedule();
4060
+				MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF0000) | val;
4061
+				return;
4062
+			case REG_IE + 2 :
4063
+				NDS_Reschedule();
4064
+				//emu_halt();
4065
+				MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF) | (((uint32_t)val)<<16);
4066
+				return;
4067
+
4068
+			case REG_IF: REG_IF_WriteWord<ARMCPU_ARM7>(0,val); return;
4069
+			case REG_IF+2: REG_IF_WriteWord<ARMCPU_ARM7>(2,val); return;
4070
+
4071
+            case REG_IPCSYNC :
4072
+				MMU_IPCSync(ARMCPU_ARM7, val);
4073
+				return;
4074
+
4075
+			case REG_IPCFIFOCNT :
4076
+				IPC_FIFOcnt(ARMCPU_ARM7, val);
4077
+				return;
4078
+            case REG_TM0CNTL :
4079
+            case REG_TM1CNTL :
4080
+            case REG_TM2CNTL :
4081
+            case REG_TM3CNTL :
4082
+				MMU.timerReload[ARMCPU_ARM7][(adr>>2)&3] = val;
4083
+				return;
4084
+			case REG_TM0CNTH :
4085
+			case REG_TM1CNTH :
4086
+			case REG_TM2CNTH :
4087
+			case REG_TM3CNTH :
4088
+			{
4089
+				int timerIndex	= ((adr-2)>>2)&0x3;
4090
+				write_timer(ARMCPU_ARM7, timerIndex, val);
4091
+				return;
4092
+			}
4093
+
4094
+			case REG_GCROMCTRL :
4095
+				MMU_writeToGCControl<ARMCPU_ARM7>( (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF0000) | val);
4096
+				return;
4097
+			case REG_GCROMCTRL+2 :
4098
+				MMU_writeToGCControl<ARMCPU_ARM7>( (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0xFFFF) | ((uint32_t) val << 16));
4099
+				return;
4100
+		}
4101
+
4102
+		T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
4103
+		return;
4104
+	}
4105
+
4106
+	//bool unmapped = false/*, restricted*/;
4107
+	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4108
+	//if(unmapped) return;
4109
+
4110
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
4111
+	T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
4112
+}
4113
+//================================================= MMU ARM7 write 32
4114
+void FASTCALL _MMU_ARM7_write32(uint32_t adr, uint32_t val)
4115
+{
4116
+	adr &= 0x0FFFFFFC;
4117
+
4118
+	//mmu_log_debug_ARM7(adr, "(write32) 0x%08X", val);
4119
+
4120
+	if (adr < 0x4000) return;	// PU BIOS
4121
+
4122
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
4123
+	{
4124
+		//addon.write32(adr, val);
4125
+		return;
4126
+	}
4127
+
4128
+	/*if ((adr & 0xFFFF0000) == 0x04800000)
4129
+	{
4130
+		WIFI_write16(adr, val & 0xFFFF);
4131
+		WIFI_write16(adr+2, val >> 16);
4132
+		T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x48], adr&MMU.MMU_MASK[ARMCPU_ARM7][0x48], val);
4133
+		return;
4134
+	}*/
4135
+
4136
+    if ((adr>=0x04000400)&&(adr<0x04000520))
4137
+    {
4138
+        SPU_WriteLong(adr, val);
4139
+        return;
4140
+    }
4141
+
4142
+	if((adr>>24)==4)
4143
+	{
4144
+		if(MMU_new.is_dma(adr)) { MMU_new.write_dma(ARMCPU_ARM7,32,adr,val); return; }
4145
+
4146
+		switch(adr)
4147
+		{
4148
+			/*case REG_RTC:
4149
+				rtcWrite((uint16_t)val);
4150
+				break;*/
4151
+
4152
+			case REG_IME :
4153
+				NDS_Reschedule();
4154
+				MMU.reg_IME[ARMCPU_ARM7] = val & 0x01;
4155
+				T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x208, val);
4156
+				return;
4157
+
4158
+			case REG_IE :
4159
+				NDS_Reschedule();
4160
+				MMU.reg_IE[ARMCPU_ARM7] = val;
4161
+				return;
4162
+
4163
+			case REG_IF: REG_IF_WriteLong<ARMCPU_ARM7>(val); return;
4164
+
4165
+            case REG_TM0CNTL:
4166
+            case REG_TM1CNTL:
4167
+            case REG_TM2CNTL:
4168
+            case REG_TM3CNTL:
4169
+			{
4170
+				int timerIndex = (adr>>2)&0x3;
4171
+				MMU.timerReload[ARMCPU_ARM7][timerIndex] = (uint16_t)val;
4172
+				T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & 0xFFF, static_cast<uint16_t>(val));
4173
+				write_timer(ARMCPU_ARM7, timerIndex, val>>16);
4174
+				return;
4175
+			}
4176
+
4177
+			case REG_IPCSYNC:
4178
+				MMU_IPCSync(ARMCPU_ARM7, val);
4179
+				return;
4180
+			case REG_IPCFIFOCNT:
4181
+				IPC_FIFOcnt(ARMCPU_ARM7, static_cast<uint16_t>(val));
4182
+				return;
4183
+			case REG_IPCFIFOSEND:
4184
+				IPC_FIFOsend(ARMCPU_ARM7, val);
4185
+				return;
4186
+
4187
+			case REG_GCROMCTRL :
4188
+				MMU_writeToGCControl<ARMCPU_ARM7>(val);
4189
+				return;
4190
+
4191
+			case REG_GCDATAIN:
4192
+				slot1_device.write32(ARMCPU_ARM7, REG_GCDATAIN,val);
4193
+				return;
4194
+		}
4195
+		T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
4196
+		return;
4197
+	}
4198
+
4199
+	//bool unmapped = false/*, restricted*/;
4200
+	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4201
+	//if(unmapped) return;
4202
+
4203
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [shash]
4204
+	T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
4205
+}
4206
+
4207
+//================================================= MMU ARM7 read 08
4208
+uint8_t FASTCALL _MMU_ARM7_read08(uint32_t adr)
4209
+{
4210
+	adr &= 0x0FFFFFFF;
4211
+
4212
+	//mmu_log_debug_ARM7(adr, "(read08) 0x%02X", MMU.MMU_MEM[ARMCPU_ARM7][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM7][(adr>>20)&0xFF]]);
4213
+
4214
+	if (adr < 0x4000)
4215
+	{
4216
+		//uint32_t prot = T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x04000308 & MMU.MMU_MASK[ARMCPU_ARM7][0x40]);
4217
+		//if (prot) INFO("MMU7 read 08 at 0x%08X (PC 0x%08X) BIOSPROT address 0x%08X\n", adr, NDS_ARM7.R[15], prot);
4218
+
4219
+		//How accurate is this? our R[15] may not be exactly what the hardware uses (may use something less by up to 0x08)
4220
+		//This may be inaccurate at the very edge cases.
4221
+		if (NDS_ARM7.R[15] > 0x3FFF)
4222
+			return 0xFF;
4223
+	}
4224
+
4225
+	// wifi mac access
4226
+	/*if ((adr & 0xFFFF0000) == 0x04800000)
4227
+	{
4228
+		if (adr & 1)
4229
+			return (WIFI_read16(adr-1) >> 8) & 0xFF;
4230
+		else
4231
+			return WIFI_read16(adr) & 0xFF;
4232
+	}*/
4233
+
4234
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
4235
+		return 0/*addon.read08(adr)*/;
4236
+
4237
+    if ((adr>=0x04000400)&&(adr<0x04000520))
4238
+    {
4239
+        return SPU_ReadByte(adr);
4240
+    }
4241
+
4242
+	//if (adr == REG_RTC) return (uint8_t)rtcRead();
4243
+
4244
+	if (adr >> 24 == 4)
4245
+	{
4246
+		if(MMU_new.is_dma(adr)) return static_cast<uint8_t>(MMU_new.read_dma(ARMCPU_ARM7,8,adr));
4247
+
4248
+		// Address is an IO register
4249
+
4250
+		switch(adr)
4251
+		{
4252
+			case REG_IF: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>());
4253
+			case REG_IF+1: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>()>>8);
4254
+			case REG_IF+2: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>()>>16);
4255
+			case REG_IF+3: return static_cast<uint8_t>(MMU.gen_IF<ARMCPU_ARM7>()>>24);
4256
+
4257
+			/*case REG_DISPx_VCOUNT: return nds.VCount&0xFF;
4258
+			case REG_DISPx_VCOUNT+1: return (nds.VCount>>8)&0xFF;*/
4259
+		}
4260
+
4261
+		return MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]];
4262
+	}
4263
+
4264
+	//bool unmapped = false/*, restricted*/;
4265
+	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4266
+	//if(unmapped) return 0;
4267
+
4268
+    return MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]];
4269
+}
4270
+//================================================= MMU ARM7 read 16
4271
+uint16_t FASTCALL _MMU_ARM7_read16(uint32_t adr)
4272
+{
4273
+	adr &= 0x0FFFFFFE;
4274
+
4275
+	//mmu_log_debug_ARM7(adr, "(read16) 0x%04X", T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(adr>>20)&0xFF], adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr>>20)&0xFF]));
4276
+
4277
+	if (adr < 0x4000)
4278
+	{
4279
+		//uint32_t prot = T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x04000308 & MMU.MMU_MASK[ARMCPU_ARM7][0x40]);
4280
+		//if (prot) INFO("MMU7 read 16 at 0x%08X (PC 0x%08X) BIOSPROT address 0x%08X\n", adr, NDS_ARM7.R[15], prot);
4281
+		if (NDS_ARM7.R[15] > 0x3FFF)
4282
+			return 0xFFFF;
4283
+	}
4284
+
4285
+	//wifi mac access
4286
+	/*if ((adr & 0xFFFF0000) == 0x04800000)
4287
+		return WIFI_read16(adr) ;*/
4288
+
4289
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
4290
+		return 0/*addon.read16(adr)*/;
4291
+
4292
+    if ((adr>=0x04000400)&&(adr<0x04000520))
4293
+    {
4294
+        return SPU_ReadWord(adr);
4295
+    }
4296
+
4297
+	if(adr>>24==4)
4298
+	{	//Address is an IO register
4299
+
4300
+		if(MMU_new.is_dma(adr)) return static_cast<uint16_t>(MMU_new.read_dma(ARMCPU_ARM7,16,adr));
4301
+
4302
+		switch(adr)
4303
+		{
4304
+			/*case REG_POWCNT2:
4305
+			{
4306
+				uint16_t ret = 0;
4307
+				ret |= nds.power2.speakers?BIT(0):0;
4308
+				ret |= nds.power2.wifi?BIT(1):0;
4309
+				return ret;
4310
+			}*/
4311
+
4312
+			//case REG_DISPx_VCOUNT: return nds.VCount;
4313
+			//case REG_RTC: return rtcRead();
4314
+			case REG_IME: return (uint16_t)MMU.reg_IME[ARMCPU_ARM7];
4315
+
4316
+			case REG_IE:
4317
+				return (uint16_t)MMU.reg_IE[ARMCPU_ARM7];
4318
+			case REG_IE + 2:
4319
+				return (uint16_t)(MMU.reg_IE[ARMCPU_ARM7]>>16);
4320
+
4321
+			case REG_IF: return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM7>());
4322
+			case REG_IF+2: return static_cast<uint16_t>(MMU.gen_IF<ARMCPU_ARM7>()>>16);
4323
+
4324
+			case REG_TM0CNTL :
4325
+			case REG_TM1CNTL :
4326
+			case REG_TM2CNTL :
4327
+			case REG_TM3CNTL :
4328
+				return read_timer(ARMCPU_ARM7,(adr&0xF)>>2);
4329
+
4330
+			/*case REG_AUXSPICNT:
4331
+				return MMU.AUX_SPI_CNT;*/
4332
+
4333
+			/*case REG_KEYINPUT:
4334
+				//here is an example of what not to do:
4335
+				//since the arm7 polls this (and EXTKEYIN) every frame, we shouldnt count this as an input check
4336
+				//LagFrameFlag=0;
4337
+				break;*/
4338
+
4339
+			/*case REG_EXTKEYIN:
4340
+				{
4341
+					//this is gross. we should generate this whole reg instead of poking it in ndssystem
4342
+					uint16_t ret = MMU.ARM7_REG[0x136];
4343
+					if(nds.isTouch) ret &= ~64;
4344
+					else ret |= 64;
4345
+					return ret;
4346
+				}*/
4347
+		}
4348
+		return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]);
4349
+	}
4350
+
4351
+	//bool unmapped = false/*, restricted*/;
4352
+	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4353
+	//if(unmapped) return 0;
4354
+
4355
+	/* Returns data from memory */
4356
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF
4357
+	return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]);
4358
+}
4359
+//================================================= MMU ARM7 read 32
4360
+uint32_t FASTCALL _MMU_ARM7_read32(uint32_t adr)
4361
+{
4362
+	adr &= 0x0FFFFFFC;
4363
+
4364
+	//mmu_log_debug_ARM7(adr, "(read32) 0x%08X", T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][(adr>>20)&0xFF], adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr>>20)&0xFF]));
4365
+
4366
+	if (adr < 0x4000)
4367
+	{
4368
+		//uint32_t prot = T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x04000308 & MMU.MMU_MASK[ARMCPU_ARM7][0x40]);
4369
+		//if (prot) INFO("MMU7 read 32 at 0x%08X (PC 0x%08X) BIOSPROT address 0x%08X\n", adr, NDS_ARM7.R[15], prot);
4370
+		if (NDS_ARM7.R[15] > 0x3FFF)
4371
+			return 0xFFFFFFFF;
4372
+	}
4373
+
4374
+	//wifi mac access
4375
+	/*if ((adr & 0xFFFF0000) == 0x04800000)
4376
+		return WIFI_read16(adr) | (WIFI_read16(adr+2) << 16);*/
4377
+
4378
+	if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
4379
+		return 0/*addon.read32(adr)*/;
4380
+
4381
+    if ((adr>=0x04000400)&&(adr<0x04000520))
4382
+    {
4383
+        return SPU_ReadLong(adr);
4384
+    }
4385
+
4386
+	if((adr >> 24) == 4)
4387
+	{	//Address is an IO register
4388
+
4389
+		if(MMU_new.is_dma(adr)) return MMU_new.read_dma(ARMCPU_ARM7,32,adr);
4390
+
4391
+		switch(adr)
4392
+		{
4393
+			//case REG_RTC: return (uint32_t)rtcRead();
4394
+			//case REG_DISPx_VCOUNT: return nds.VCount;
4395
+
4396
+			case REG_IME :
4397
+				return MMU.reg_IME[ARMCPU_ARM7];
4398
+			case REG_IE :
4399
+				return MMU.reg_IE[ARMCPU_ARM7];
4400
+			case REG_IF: return MMU.gen_IF<ARMCPU_ARM7>();
4401
+			case REG_IPCFIFORECV :
4402
+				return IPC_FIFOrecv(ARMCPU_ARM7);
4403
+            case REG_TM0CNTL :
4404
+            case REG_TM1CNTL :
4405
+            case REG_TM2CNTL :
4406
+            case REG_TM3CNTL :
4407
+			{
4408
+				uint32_t val = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], (adr + 2) & 0xFFF);
4409
+				return MMU.timer[ARMCPU_ARM7][(adr&0xF)>>2] | (val<<16);
4410
+			}
4411
+			case REG_GCROMCTRL:
4412
+			{
4413
+				//INFO("arm7 romctrl read\n");
4414
+				break;
4415
+			}
4416
+            case REG_GCDATAIN:
4417
+				return MMU_readFromGC<ARMCPU_ARM7>();
4418
+
4419
+		}
4420
+		return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]);
4421
+	}
4422
+
4423
+	//bool unmapped = false/*, restricted*/;
4424
+	//adr = MMU_LCDmap<ARMCPU_ARM7>(adr,unmapped, restricted);
4425
+	//if(unmapped) return 0;
4426
+
4427
+	//Returns data from memory
4428
+	// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFF [zeromus, inspired by shash]
4429
+	return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]);
4430
+}
4431
+
4432
+//=========================================================================================================
4433
+
4434
+/*uint32_t FASTCALL MMU_read32(uint32_t proc, uint32_t adr)
4435
+{
4436
+	ASSERT_UNALIGNED((adr&3)==0);
4437
+
4438
+	if(proc==0)
4439
+		return _MMU_ARM9_read32(adr);
4440
+	else
4441
+		return _MMU_ARM7_read32(adr);
4442
+}*/
4443
+
4444
+/*uint16_t FASTCALL MMU_read16(uint32_t proc, uint32_t adr)
4445
+{
4446
+	ASSERT_UNALIGNED((adr&1)==0);
4447
+
4448
+	if(proc==0)
4449
+		return _MMU_ARM9_read16(adr);
4450
+	else
4451
+		return _MMU_ARM7_read16(adr);
4452
+}*/
4453
+
4454
+/*uint8_t FASTCALL MMU_read8(uint32_t proc, uint32_t adr)
4455
+{
4456
+	if(proc==0)
4457
+		return _MMU_ARM9_read08(adr);
4458
+	else
4459
+		return _MMU_ARM7_read08(adr);
4460
+}*/
4461
+
4462
+/*void FASTCALL MMU_write32(uint32_t proc, uint32_t adr, uint32_t val)
4463
+{
4464
+	ASSERT_UNALIGNED((adr&3)==0);
4465
+
4466
+	if(proc==0)
4467
+		_MMU_ARM9_write32(adr, val);
4468
+	else
4469
+		_MMU_ARM7_write32(adr,val);
4470
+}*/
4471
+
4472
+/*void FASTCALL MMU_write16(uint32_t proc, uint32_t adr, uint16_t val)
4473
+{
4474
+	ASSERT_UNALIGNED((adr&1)==0);
4475
+
4476
+	if(proc==0)
4477
+		_MMU_ARM9_write16(adr, val);
4478
+	else
4479
+		_MMU_ARM7_write16(adr,val);
4480
+}*/
4481
+
4482
+/*void FASTCALL MMU_write8(uint32_t proc, uint32_t adr, uint8_t val)
4483
+{
4484
+	if(proc==0)
4485
+		_MMU_ARM9_write08(adr, val);
4486
+	else
4487
+		_MMU_ARM7_write08(adr,val);
4488
+}*/
4489
+
4490
+/*void FASTCALL MMU_DumpMemBlock(uint8_t proc, uint32_t address, uint32_t size, uint8_t *buffer)
4491
+{
4492
+	uint32_t i;
4493
+	uint32_t curaddr;
4494
+
4495
+	for(i = 0, curaddr = address; i < size; i++, curaddr++)
4496
+	{
4497
+		buffer[i] = _MMU_read08(proc,MMU_AT_DEBUG,curaddr);
4498
+	}
4499
+}*/
4500
+
4501
+
4502
+//these templates needed to be instantiated manually
4503
+template uint32_t MMU_struct::gen_IF<ARMCPU_ARM9>();
4504
+template uint32_t MMU_struct::gen_IF<ARMCPU_ARM7>();
4505
+
4506
+////////////////////////////////////////////////////////////
4507
+//function pointer handlers for gdb stub stuff
4508
+
4509
+/*static uint16_t FASTCALL arm9_prefetch16( void *, uint32_t adr) {
4510
+	return _MMU_read16<ARMCPU_ARM9,MMU_AT_CODE>(adr);
4511
+}
4512
+
4513
+static uint32_t FASTCALL arm9_prefetch32( void *, uint32_t adr) {
4514
+	return _MMU_read32<ARMCPU_ARM9,MMU_AT_CODE>(adr);
4515
+}
4516
+
4517
+static uint8_t FASTCALL arm9_read8( void *, uint32_t adr) {
4518
+	return _MMU_read08<ARMCPU_ARM9>(adr);
4519
+}
4520
+
4521
+static uint16_t FASTCALL arm9_read16( void *, uint32_t adr) {
4522
+	return _MMU_read16<ARMCPU_ARM9>(adr);
4523
+}
4524
+
4525
+static uint32_t FASTCALL arm9_read32( void *, uint32_t adr) {
4526
+	return _MMU_read32<ARMCPU_ARM9>(adr);
4527
+}
4528
+
4529
+static void FASTCALL arm9_write8(void *, uint32_t adr, uint8_t val) {
4530
+	_MMU_write08<ARMCPU_ARM9>(adr, val);
4531
+}
4532
+
4533
+static void FASTCALL arm9_write16(void *, uint32_t adr, uint16_t val) {
4534
+	_MMU_write16<ARMCPU_ARM9>(adr, val);
4535
+}
4536
+
4537
+static void FASTCALL arm9_write32(void *, uint32_t adr, uint32_t val) {
4538
+	_MMU_write32<ARMCPU_ARM9>(adr, val);
4539
+}
4540
+
4541
+static uint16_t FASTCALL arm7_prefetch16( void *, uint32_t adr) {
4542
+  return _MMU_read16<ARMCPU_ARM7,MMU_AT_CODE>(adr);
4543
+}
4544
+
4545
+static uint32_t FASTCALL arm7_prefetch32( void *, uint32_t adr) {
4546
+  return _MMU_read32<ARMCPU_ARM7,MMU_AT_CODE>(adr);
4547
+}
4548
+
4549
+static uint8_t FASTCALL arm7_read8( void *, uint32_t adr) {
4550
+  return _MMU_read08<ARMCPU_ARM7>(adr);
4551
+}
4552
+
4553
+static uint16_t FASTCALL arm7_read16( void *, uint32_t adr) {
4554
+  return _MMU_read16<ARMCPU_ARM7>(adr);
4555
+}
4556
+
4557
+static uint32_t FASTCALL arm7_read32( void *, uint32_t adr) {
4558
+  return _MMU_read32<ARMCPU_ARM7>(adr);
4559
+}
4560
+
4561
+static void FASTCALL arm7_write8(void *, uint32_t adr, uint8_t val) {
4562
+  _MMU_write08<ARMCPU_ARM7>(adr, val);
4563
+}
4564
+
4565
+static void FASTCALL arm7_write16(void *, uint32_t adr, uint16_t val) {
4566
+  _MMU_write16<ARMCPU_ARM7>(adr, val);
4567
+}
4568
+
4569
+static void FASTCALL arm7_write32(void *, uint32_t adr, uint32_t val) {
4570
+  _MMU_write32<ARMCPU_ARM7>(adr, val);
4571
+}*/
4572
+
4573
+
4574
+
4575
+/*
4576
+ * the base memory interfaces
4577
+ */
4578
+/*struct armcpu_memory_iface arm9_base_memory_iface = {
4579
+  arm9_prefetch32,
4580
+  arm9_prefetch16,
4581
+
4582
+  arm9_read8,
4583
+  arm9_read16,
4584
+  arm9_read32,
4585
+
4586
+  arm9_write8,
4587
+  arm9_write16,
4588
+  arm9_write32
4589
+};
4590
+
4591
+struct armcpu_memory_iface arm7_base_memory_iface = {
4592
+  arm7_prefetch32,
4593
+  arm7_prefetch16,
4594
+
4595
+  arm7_read8,
4596
+  arm7_read16,
4597
+  arm7_read32,
4598
+
4599
+  arm7_write8,
4600
+  arm7_write16,
4601
+  arm7_write32
4602
+};*/
4603
+
4604
+/*
4605
+ * The direct memory interface for the ARM9.
4606
+ * This avoids the ARM9 protection unit when accessing
4607
+ * memory.
4608
+ */
4609
+/*struct armcpu_memory_iface arm9_direct_memory_iface = {
4610
+  NULL,
4611
+  NULL,
4612
+
4613
+  arm9_read8,
4614
+  arm9_read16,
4615
+  arm9_read32,
4616
+
4617
+  arm9_write8,
4618
+  arm9_write16,
4619
+  arm9_write32
4620
+};*/
4621
+
4622
+
4623
+/////////////////////////////////////////////////////////////////
4624
+/////////////////////////////////////////////////////////////////
4625
+/////////////////////////////////////////////////////////////////
4626
+/////////////////////////////////////////////////////////////////
4627
+/////////////////////////////////////////////////////////////////
4628
+/////////////////////////////////////////////////////////////////
4629
+
4630
+//#ifdef PROFILE_MEMORY_ACCESS
4631
+//
4632
+//#define PROFILE_PREFETCH 0
4633
+//#define PROFILE_READ 1
4634
+//#define PROFILE_WRITE 2
4635
+//
4636
+//struct mem_access_profile {
4637
+//  uint64_t num_accesses;
4638
+//  uint32_t address_mask;
4639
+//  uint32_t masked_value;
4640
+//};
4641
+//
4642
+//#define PROFILE_NUM_MEM_ACCESS_PROFILES 4
4643
+//
4644
+//static uint64_t profile_num_accesses[2][3];
4645
+//static uint64_t profile_unknown_addresses[2][3];
4646
+//static struct mem_access_profile
4647
+//profile_memory_accesses[2][3][PROFILE_NUM_MEM_ACCESS_PROFILES];
4648
+//
4649
+//static void
4650
+//setup_profiling() {
4651
+//  int i;
4652
+//
4653
+//  for ( i = 0; i < 2; i++) {
4654
+//    int access_type;
4655
+//
4656
+//    for ( access_type = 0; access_type < 3; access_type++) {
4657
+//      profile_num_accesses[i][access_type] = 0;
4658
+//      profile_unknown_addresses[i][access_type] = 0;
4659
+//
4660
+//      /*
4661
+//       * Setup the access testing structures
4662
+//       */
4663
+//      profile_memory_accesses[i][access_type][0].address_mask = 0x0e000000;
4664
+//      profile_memory_accesses[i][access_type][0].masked_value = 0x00000000;
4665
+//      profile_memory_accesses[i][access_type][0].num_accesses = 0;
4666
+//
4667
+//      /* main memory */
4668
+//      profile_memory_accesses[i][access_type][1].address_mask = 0x0f000000;
4669
+//      profile_memory_accesses[i][access_type][1].masked_value = 0x02000000;
4670
+//      profile_memory_accesses[i][access_type][1].num_accesses = 0;
4671
+//
4672
+//      /* shared memory */
4673
+//      profile_memory_accesses[i][access_type][2].address_mask = 0x0f800000;
4674
+//      profile_memory_accesses[i][access_type][2].masked_value = 0x03000000;
4675
+//      profile_memory_accesses[i][access_type][2].num_accesses = 0;
4676
+//
4677
+//      /* arm7 memory */
4678
+//      profile_memory_accesses[i][access_type][3].address_mask = 0x0f800000;
4679
+//      profile_memory_accesses[i][access_type][3].masked_value = 0x03800000;
4680
+//      profile_memory_accesses[i][access_type][3].num_accesses = 0;
4681
+//    }
4682
+//  }
4683
+//}
4684
+//
4685
+//static void
4686
+//profile_memory_access( int arm9, uint32_t adr, int access_type) {
4687
+//  static int first = 1;
4688
+//  int mem_profile;
4689
+//  int address_found = 0;
4690
+//
4691
+//  if ( first) {
4692
+//    setup_profiling();
4693
+//    first = 0;
4694
+//  }
4695
+//
4696
+//  profile_num_accesses[arm9][access_type] += 1;
4697
+//
4698
+//  for ( mem_profile = 0;
4699
+//        mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES &&
4700
+//          !address_found;
4701
+//        mem_profile++) {
4702
+//    if ( (adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask) ==
4703
+//         profile_memory_accesses[arm9][access_type][mem_profile].masked_value) {
4704
+//      /*printf( "adr %08x mask %08x res %08x expected %08x\n",
4705
+//              adr,
4706
+//              profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
4707
+//              adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
4708
+//              profile_memory_accesses[arm9][access_type][mem_profile].masked_value);*/
4709
+//      address_found = 1;
4710
+//      profile_memory_accesses[arm9][access_type][mem_profile].num_accesses += 1;
4711
+//    }
4712
+//  }
4713
+//
4714
+//  if ( !address_found) {
4715
+//    profile_unknown_addresses[arm9][access_type] += 1;
4716
+//  }
4717
+//}
4718
+//
4719
+//
4720
+//static const char *access_type_strings[] = {
4721
+//  "prefetch",
4722
+//  "read    ",
4723
+//  "write   "
4724
+//};
4725
+//
4726
+//void
4727
+//print_memory_profiling() {
4728
+//  int arm;
4729
+//
4730
+//  printf("------ Memory access profile ------\n");
4731
+//
4732
+//  for ( arm = 0; arm < 2; arm++) {
4733
+//    int access_type;
4734
+//
4735
+//    for ( access_type = 0; access_type < 3; access_type++) {
4736
+//      int mem_profile;
4737
+//      printf("ARM%c: num of %s %lld\n",
4738
+//             arm ? '9' : '7',
4739
+//             access_type_strings[access_type],
4740
+//             profile_num_accesses[arm][access_type]);
4741
+//
4742
+//      for ( mem_profile = 0;
4743
+//            mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES;
4744
+//            mem_profile++) {
4745
+//        printf( "address %08x: %lld\n",
4746
+//                profile_memory_accesses[arm][access_type][mem_profile].masked_value,
4747
+//                profile_memory_accesses[arm][access_type][mem_profile].num_accesses);
4748
+//      }
4749
+//
4750
+//      printf( "unknown addresses %lld\n",
4751
+//              profile_unknown_addresses[arm][access_type]);
4752
+//
4753
+//      printf( "\n");
4754
+//    }
4755
+//  }
4756
+//
4757
+//  printf("------ End of Memory access profile ------\n\n");
4758
+//}
4759
+//#else
4760
+//void
4761
+//print_memory_profiling() {
4762
+//}
4763
+//#endif /* End of PROFILE_MEMORY_ACCESS area */