| ... | ... |
@@ -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: |
* 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).
| ... | ... |
@@ -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 |
|
* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
| ... | ... |
@@ -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 |
{
|
| ... | ... |
@@ -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. |
| ... | ... |
@@ -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: |
| ... | ... |
@@ -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(®_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(®isters[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 */ |
| ... | ... |
@@ -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; |
| 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(®_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(®isters[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 */ |