* 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).
| ... | ... |
@@ -31,36 +31,36 @@ uint32_t cpuPrefetch[2]; |
| 31 | 31 |
|
| 32 | 32 |
int cpuTotalTicks = 0; |
| 33 | 33 |
|
| 34 |
-int lcdTicks = 208; |
|
| 35 |
-uint8_t timerOnOffDelay = 0; |
|
| 36 |
-uint16_t timer0Value = 0; |
|
| 34 |
+static int lcdTicks = 208; |
|
| 35 |
+static uint8_t timerOnOffDelay = 0; |
|
| 36 |
+static uint16_t timer0Value = 0; |
|
| 37 | 37 |
bool timer0On = false; |
| 38 | 38 |
int timer0Ticks = 0; |
| 39 |
-int timer0Reload = 0; |
|
| 39 |
+static int timer0Reload = 0; |
|
| 40 | 40 |
int timer0ClockReload = 0; |
| 41 |
-uint16_t timer1Value = 0; |
|
| 41 |
+static uint16_t timer1Value = 0; |
|
| 42 | 42 |
bool timer1On = false; |
| 43 | 43 |
int timer1Ticks = 0; |
| 44 |
-int timer1Reload = 0; |
|
| 44 |
+static int timer1Reload = 0; |
|
| 45 | 45 |
int timer1ClockReload = 0; |
| 46 |
-uint16_t timer2Value = 0; |
|
| 46 |
+static uint16_t timer2Value = 0; |
|
| 47 | 47 |
bool timer2On = false; |
| 48 | 48 |
int timer2Ticks = 0; |
| 49 |
-int timer2Reload = 0; |
|
| 49 |
+static int timer2Reload = 0; |
|
| 50 | 50 |
int timer2ClockReload = 0; |
| 51 |
-uint16_t timer3Value = 0; |
|
| 51 |
+static uint16_t timer3Value = 0; |
|
| 52 | 52 |
bool timer3On = false; |
| 53 | 53 |
int timer3Ticks = 0; |
| 54 |
-int timer3Reload = 0; |
|
| 54 |
+static int timer3Reload = 0; |
|
| 55 | 55 |
int timer3ClockReload = 0; |
| 56 |
-uint32_t dma0Source = 0; |
|
| 57 |
-uint32_t dma0Dest = 0; |
|
| 58 |
-uint32_t dma1Source = 0; |
|
| 59 |
-uint32_t dma1Dest = 0; |
|
| 60 |
-uint32_t dma2Source = 0; |
|
| 61 |
-uint32_t dma2Dest = 0; |
|
| 62 |
-uint32_t dma3Source = 0; |
|
| 63 |
-uint32_t dma3Dest = 0; |
|
| 56 |
+static uint32_t dma0Source = 0; |
|
| 57 |
+static uint32_t dma0Dest = 0; |
|
| 58 |
+static uint32_t dma1Source = 0; |
|
| 59 |
+static uint32_t dma1Dest = 0; |
|
| 60 |
+static uint32_t dma2Source = 0; |
|
| 61 |
+static uint32_t dma2Dest = 0; |
|
| 62 |
+static uint32_t dma3Source = 0; |
|
| 63 |
+static uint32_t dma3Dest = 0; |
|
| 64 | 64 |
|
| 65 | 65 |
static const int TIMER_TICKS[] = { 0, 6, 8, 10 };
|
| 66 | 66 |
|
| ... | ... |
@@ -83,14 +83,13 @@ uint8_t memoryWaitSeq32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 }
|
| 83 | 83 |
//const u8 videoMemoryWait[16] = |
| 84 | 84 |
// {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
| 85 | 85 |
|
| 86 |
- |
|
| 87 | 86 |
uint8_t biosProtected[4]; |
| 88 | 87 |
|
| 89 | 88 |
#ifdef WORDS_BIGENDIAN |
| 90 |
-bool cpuBiosSwapped = false; |
|
| 89 |
+static bool cpuBiosSwapped = false; |
|
| 91 | 90 |
#endif |
| 92 | 91 |
|
| 93 |
-uint32_t myROM[] = |
|
| 92 |
+static uint32_t myROM[] = |
|
| 94 | 93 |
{
|
| 95 | 94 |
0xEA000006, |
| 96 | 95 |
0xEA000093, |
| ... | ... |
@@ -1505,7 +1505,7 @@ void CPUInit() |
| 1505 | 1505 |
cpuBitsSet[i] = count; |
| 1506 | 1506 |
} |
| 1507 | 1507 |
|
| 1508 |
- std::fill(&ioReadable[0], &ioReadable[0x304], true); |
|
| 1508 |
+ std::fill_n(&ioReadable[0], 0x304, true); |
|
| 1509 | 1509 |
std::fill(&ioReadable[0x10], &ioReadable[0x48], false); |
| 1510 | 1510 |
std::fill(&ioReadable[0x4c], &ioReadable[0x50], false); |
| 1511 | 1511 |
std::fill(&ioReadable[0x54], &ioReadable[0x60], false); |
| ... | ... |
@@ -1,6 +1,4 @@ |
| 1 | 1 |
#include <algorithm> |
| 2 |
-#include <cstdlib> |
|
| 3 |
-#include <cstring> |
|
| 4 | 2 |
#include "GBA.h" |
| 5 | 3 |
#include "GBAcpu.h" |
| 6 | 4 |
#include "GBAinline.h" |
| ... | ... |
@@ -19,7 +17,8 @@ bool busPrefetch = false; |
| 19 | 17 |
bool busPrefetchEnable = false; |
| 20 | 18 |
uint32_t busPrefetchCount = 0; |
| 21 | 19 |
static int cpuDmaTicksToUpdate = 0; |
| 22 |
-static uint32_t cpuDmaLast = 0; |
|
| 20 |
+bool cpuDmaHack = false; |
|
| 21 |
+uint32_t cpuDmaLast = 0; |
|
| 23 | 22 |
static int dummyAddress = 0; |
| 24 | 23 |
|
| 25 | 24 |
int cpuNextEvent = 0; |
| ... | ... |
@@ -27,7 +26,6 @@ int cpuNextEvent = 0; |
| 27 | 26 |
static bool intState = false; |
| 28 | 27 |
bool stopState = false; |
| 29 | 28 |
bool holdState = false; |
| 30 |
-int holdType = 0; |
|
| 31 | 29 |
|
| 32 | 30 |
uint32_t cpuPrefetch[2]; |
| 33 | 31 |
|
| ... | ... |
@@ -63,8 +61,6 @@ uint32_t dma2Source = 0; |
| 63 | 61 |
uint32_t dma2Dest = 0; |
| 64 | 62 |
uint32_t dma3Source = 0; |
| 65 | 63 |
uint32_t dma3Dest = 0; |
| 66 |
-char buffer[1024]; |
|
| 67 |
-int count = 0; |
|
| 68 | 64 |
|
| 69 | 65 |
static const int TIMER_TICKS[] = { 0, 6, 8, 10 };
|
| 70 | 66 |
|
| ... | ... |
@@ -80,6 +76,14 @@ uint8_t memoryWait32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
|
| 80 | 76 |
uint8_t memoryWaitSeq[] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
|
| 81 | 77 |
uint8_t memoryWaitSeq32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
|
| 82 | 78 |
|
| 79 |
+// The videoMemoryWait constants are used to add some waitstates |
|
| 80 |
+// if the opcode access video memory data outside of vblank/hblank |
|
| 81 |
+// It seems to happen on only one ticks for each pixel. |
|
| 82 |
+// Not used for now (too problematic with current code). |
|
| 83 |
+//const u8 videoMemoryWait[16] = |
|
| 84 |
+// {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
| 85 |
+ |
|
| 86 |
+ |
|
| 83 | 87 |
uint8_t biosProtected[4]; |
| 84 | 88 |
|
| 85 | 89 |
#ifdef WORDS_BIGENDIAN |
| ... | ... |
@@ -294,17 +298,18 @@ int CPULoadRom() |
| 294 | 298 |
{
|
| 295 | 299 |
romSize = 0x2000000; |
| 296 | 300 |
|
| 301 |
+ memset(&rom[0], 0, 0x2000000); |
|
| 297 | 302 |
memset(&workRAM[0], 0, 0x40000); |
| 298 | 303 |
|
| 299 | 304 |
if (cpuIsMultiBoot) |
| 300 |
- mapgsf(workRAM, 0x40000, romSize); |
|
| 305 |
+ mapgsf(&workRAM[0], 0x40000, romSize); |
|
| 301 | 306 |
else |
| 302 |
- mapgsf(rom, 0x2000000, romSize); |
|
| 307 |
+ mapgsf(&rom[0], 0x2000000, romSize); |
|
| 303 | 308 |
|
| 304 |
- uint16_t *temp = reinterpret_cast<uint16_t *>(rom + ((romSize + 1) & ~1)); |
|
| 309 |
+ auto temp = reinterpret_cast<uint16_t *>(&rom[(romSize + 1) & ~1]); |
|
| 305 | 310 |
for (int i = (romSize + 1) & ~1; i < 0x2000000; i += 2) |
| 306 | 311 |
{
|
| 307 |
- WRITE16LE(temp, (i >> 1) & 0xFFFF); |
|
| 312 |
+ WRITE16LE(&temp[0], (i >> 1) & 0xFFFF); |
|
| 308 | 313 |
++temp; |
| 309 | 314 |
} |
| 310 | 315 |
|
| ... | ... |
@@ -353,6 +358,9 @@ void CPUUpdateFlags(bool breakLoop) |
| 353 | 358 |
|
| 354 | 359 |
void CPUSwitchMode(int mode, bool saveState, bool breakLoop) |
| 355 | 360 |
{
|
| 361 |
+ //if(armMode == mode) |
|
| 362 |
+ // return; |
|
| 363 |
+ |
|
| 356 | 364 |
CPUUpdateCPSR(); |
| 357 | 365 |
|
| 358 | 366 |
switch (armMode) |
| ... | ... |
@@ -505,7 +513,6 @@ void CPUSoftwareInterrupt(int comment) |
| 505 | 513 |
break; |
| 506 | 514 |
case 0x02: |
| 507 | 515 |
holdState = true; |
| 508 |
- holdType = -1; |
|
| 509 | 516 |
cpuNextEvent = cpuTotalTicks; |
| 510 | 517 |
break; |
| 511 | 518 |
case 0x03: |
| ... | ... |
@@ -526,41 +533,41 @@ void CPUSoftwareInterrupt(int comment) |
| 526 | 533 |
BIOS_ArcTan2(); |
| 527 | 534 |
break; |
| 528 | 535 |
case 0x0B: |
| 529 |
- {
|
|
| 530 |
- int len = (reg[2].I & 0x1FFFFF) >> 1; |
|
| 531 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 532 | 536 |
{
|
| 533 |
- if ((reg[2].I >> 24) & 1) |
|
| 537 |
+ int len = (reg[2].I & 0x1FFFFF) >> 1; |
|
| 538 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 534 | 539 |
{
|
| 535 |
- if ((reg[2].I >> 26) & 1) |
|
| 536 |
- SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); |
|
| 537 |
- else |
|
| 538 |
- SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 539 |
- } |
|
| 540 |
- else |
|
| 541 |
- {
|
|
| 542 |
- if ((reg[2].I >> 26) & 1) |
|
| 543 |
- SWITicks = (10 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); |
|
| 540 |
+ if ((reg[2].I >> 24) & 1) |
|
| 541 |
+ {
|
|
| 542 |
+ if ((reg[2].I >> 26) & 1) |
|
| 543 |
+ SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); |
|
| 544 |
+ else |
|
| 545 |
+ SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 546 |
+ } |
|
| 544 | 547 |
else |
| 545 |
- SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 548 |
+ {
|
|
| 549 |
+ if ((reg[2].I >> 26) & 1) |
|
| 550 |
+ SWITicks = (10 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); |
|
| 551 |
+ else |
|
| 552 |
+ SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 553 |
+ } |
|
| 546 | 554 |
} |
| 547 | 555 |
} |
| 548 | 556 |
BIOS_CpuSet(); |
| 549 | 557 |
break; |
| 550 |
- } |
|
| 551 | 558 |
case 0x0C: |
| 552 |
- {
|
|
| 553 |
- int len = (reg[2].I & 0x1FFFFF) >> 5; |
|
| 554 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 555 | 559 |
{
|
| 556 |
- if ((reg[2].I >> 24) & 1) |
|
| 557 |
- SWITicks = (6 + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 1)) * len; |
|
| 558 |
- else |
|
| 559 |
- SWITicks = (9 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[0].I >> 24) & 0xF] + memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 2)) * len; |
|
| 560 |
+ int len = (reg[2].I & 0x1FFFFF) >> 5; |
|
| 561 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 562 |
+ {
|
|
| 563 |
+ if ((reg[2].I >> 24) & 1) |
|
| 564 |
+ SWITicks = (6 + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 1)) * len; |
|
| 565 |
+ else |
|
| 566 |
+ SWITicks = (9 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[0].I >> 24) & 0xF] + memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 2)) * len; |
|
| 567 |
+ } |
|
| 560 | 568 |
} |
| 561 | 569 |
BIOS_CpuFastSet(); |
| 562 | 570 |
break; |
| 563 |
- } |
|
| 564 | 571 |
case 0x0D: |
| 565 | 572 |
BIOS_GetBiosChecksum(); |
| 566 | 573 |
break; |
| ... | ... |
@@ -571,77 +578,77 @@ void CPUSoftwareInterrupt(int comment) |
| 571 | 578 |
BIOS_ObjAffineSet(); |
| 572 | 579 |
break; |
| 573 | 580 |
case 0x10: |
| 574 |
- {
|
|
| 575 |
- int len = CPUReadHalfWord(reg[2].I); |
|
| 576 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 577 |
- SWITicks = (32 + memoryWait[(reg[0].I >> 24) & 0xF]) * len; |
|
| 581 |
+ {
|
|
| 582 |
+ int len = CPUReadHalfWord(reg[2].I); |
|
| 583 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 584 |
+ SWITicks = (32 + memoryWait[(reg[0].I >> 24) & 0xF]) * len; |
|
| 585 |
+ } |
|
| 578 | 586 |
BIOS_BitUnPack(); |
| 579 | 587 |
break; |
| 580 |
- } |
|
| 581 | 588 |
case 0x11: |
| 582 |
- {
|
|
| 583 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 584 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 585 |
- SWITicks = (9 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 589 |
+ {
|
|
| 590 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 591 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 592 |
+ SWITicks = (9 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 593 |
+ } |
|
| 586 | 594 |
BIOS_LZ77UnCompWram(); |
| 587 | 595 |
break; |
| 588 |
- } |
|
| 589 | 596 |
case 0x12: |
| 590 |
- {
|
|
| 591 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 592 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 593 |
- SWITicks = (19 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 597 |
+ {
|
|
| 598 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 599 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 600 |
+ SWITicks = (19 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 601 |
+ } |
|
| 594 | 602 |
BIOS_LZ77UnCompVram(); |
| 595 | 603 |
break; |
| 596 |
- } |
|
| 597 | 604 |
case 0x13: |
| 598 |
- {
|
|
| 599 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 600 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 601 |
- SWITicks = (29 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1)) * len; |
|
| 605 |
+ {
|
|
| 606 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 607 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 608 |
+ SWITicks = (29 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1)) * len; |
|
| 609 |
+ } |
|
| 602 | 610 |
BIOS_HuffUnComp(); |
| 603 | 611 |
break; |
| 604 |
- } |
|
| 605 | 612 |
case 0x14: |
| 606 |
- {
|
|
| 607 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 608 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 609 |
- SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 613 |
+ {
|
|
| 614 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 615 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 616 |
+ SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 617 |
+ } |
|
| 610 | 618 |
BIOS_RLUnCompWram(); |
| 611 | 619 |
break; |
| 612 |
- } |
|
| 613 | 620 |
case 0x15: |
| 614 |
- {
|
|
| 615 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 616 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 617 |
- SWITicks = (34 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 621 |
+ {
|
|
| 622 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 623 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 624 |
+ SWITicks = (34 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 625 |
+ } |
|
| 618 | 626 |
BIOS_RLUnCompVram(); |
| 619 | 627 |
break; |
| 620 |
- } |
|
| 621 | 628 |
case 0x16: |
| 622 |
- {
|
|
| 623 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 624 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 625 |
- SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 629 |
+ {
|
|
| 630 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 631 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 632 |
+ SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 633 |
+ } |
|
| 626 | 634 |
BIOS_Diff8bitUnFilterWram(); |
| 627 | 635 |
break; |
| 628 |
- } |
|
| 629 | 636 |
case 0x17: |
| 630 |
- {
|
|
| 631 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 632 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 633 |
- SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 637 |
+ {
|
|
| 638 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 639 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 640 |
+ SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 641 |
+ } |
|
| 634 | 642 |
BIOS_Diff8bitUnFilterVram(); |
| 635 | 643 |
break; |
| 636 |
- } |
|
| 637 | 644 |
case 0x18: |
| 638 |
- {
|
|
| 639 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 640 |
- if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 641 |
- SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 645 |
+ {
|
|
| 646 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 647 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 648 |
+ SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 649 |
+ } |
|
| 642 | 650 |
BIOS_Diff16bitUnFilter(); |
| 643 | 651 |
break; |
| 644 |
- } |
|
| 645 | 652 |
case 0x19: |
| 646 | 653 |
if (reg[0].I) |
| 647 | 654 |
soundPause(); |
| ... | ... |
@@ -657,7 +664,7 @@ void CPUSoftwareInterrupt(int comment) |
| 657 | 664 |
} |
| 658 | 665 |
} |
| 659 | 666 |
|
| 660 |
-void CPUCompareVCOUNT() |
|
| 667 |
+static void CPUCompareVCOUNT() |
|
| 661 | 668 |
{
|
| 662 | 669 |
if (VCOUNT == (DISPSTAT >> 8)) |
| 663 | 670 |
{
|
| ... | ... |
@@ -683,7 +690,7 @@ void CPUCompareVCOUNT() |
| 683 | 690 |
} |
| 684 | 691 |
} |
| 685 | 692 |
|
| 686 |
-void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int transfer32) |
|
| 693 |
+static void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int transfer32) |
|
| 687 | 694 |
{
|
| 688 | 695 |
int sm = s >> 24; |
| 689 | 696 |
int dm = d >> 24; |
| ... | ... |
@@ -691,12 +698,16 @@ void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int t |
| 691 | 698 |
int dw = 0; |
| 692 | 699 |
int sc = c; |
| 693 | 700 |
|
| 701 |
+ cpuDmaHack = true; |
|
| 694 | 702 |
// This is done to get the correct waitstates. |
| 695 | 703 |
if (sm > 15) |
| 696 | 704 |
sm = 15; |
| 697 | 705 |
if (dm > 15) |
| 698 | 706 |
dm = 15; |
| 699 | 707 |
|
| 708 |
+ //if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07)) |
|
| 709 |
+ // blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ? true : false); |
|
| 710 |
+ |
|
| 700 | 711 |
if (transfer32) |
| 701 | 712 |
{
|
| 702 | 713 |
s &= 0xFFFFFFFC; |
| ... | ... |
@@ -765,185 +776,174 @@ void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int t |
| 765 | 776 |
} |
| 766 | 777 |
|
| 767 | 778 |
cpuDmaTicksToUpdate += totalTicks; |
| 779 |
+ cpuDmaHack = false; |
|
| 768 | 780 |
} |
| 769 | 781 |
|
| 770 | 782 |
void CPUCheckDMA(int reason, int dmamask) |
| 771 | 783 |
{
|
| 772 | 784 |
// DMA 0 |
| 773 |
- if ((DM0CNT_H & 0x8000) && (dmamask & 1)) |
|
| 785 |
+ if ((DM0CNT_H & 0x8000) && (dmamask & 1) && ((DM0CNT_H >> 12) & 3) == reason) |
|
| 774 | 786 |
{
|
| 775 |
- if (((DM0CNT_H >> 12) & 3) == reason) |
|
| 787 |
+ uint32_t sourceIncrement = 4; |
|
| 788 |
+ uint32_t destIncrement = 4; |
|
| 789 |
+ switch ((DM0CNT_H >> 7) & 3) |
|
| 776 | 790 |
{
|
| 777 |
- uint32_t sourceIncrement = 4; |
|
| 778 |
- uint32_t destIncrement = 4; |
|
| 779 |
- switch ((DM0CNT_H >> 7) & 3) |
|
| 780 |
- {
|
|
| 781 |
- case 1: |
|
| 782 |
- sourceIncrement = static_cast<uint32_t>(-4); |
|
| 783 |
- break; |
|
| 784 |
- case 2: |
|
| 785 |
- sourceIncrement = 0; |
|
| 786 |
- } |
|
| 787 |
- switch ((DM0CNT_H >> 5) & 3) |
|
| 788 |
- {
|
|
| 789 |
- case 1: |
|
| 790 |
- destIncrement = static_cast<uint32_t>(-4); |
|
| 791 |
- break; |
|
| 792 |
- case 2: |
|
| 793 |
- destIncrement = 0; |
|
| 794 |
- } |
|
| 795 |
- doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, DM0CNT_L ? DM0CNT_L : 0x4000, DM0CNT_H & 0x0400); |
|
| 791 |
+ case 1: |
|
| 792 |
+ sourceIncrement = static_cast<uint32_t>(-4); |
|
| 793 |
+ break; |
|
| 794 |
+ case 2: |
|
| 795 |
+ sourceIncrement = 0; |
|
| 796 |
+ } |
|
| 797 |
+ switch ((DM0CNT_H >> 5) & 3) |
|
| 798 |
+ {
|
|
| 799 |
+ case 1: |
|
| 800 |
+ destIncrement = static_cast<uint32_t>(-4); |
|
| 801 |
+ break; |
|
| 802 |
+ case 2: |
|
| 803 |
+ destIncrement = 0; |
|
| 804 |
+ } |
|
| 805 |
+ doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, DM0CNT_L ? DM0CNT_L : 0x4000, DM0CNT_H & 0x0400); |
|
| 796 | 806 |
|
| 797 |
- if (DM0CNT_H & 0x4000) |
|
| 798 |
- {
|
|
| 799 |
- IF |= 0x0100; |
|
| 800 |
- UPDATE_REG(0x202, IF); |
|
| 801 |
- cpuNextEvent = cpuTotalTicks; |
|
| 802 |
- } |
|
| 807 |
+ if (DM0CNT_H & 0x4000) |
|
| 808 |
+ {
|
|
| 809 |
+ IF |= 0x0100; |
|
| 810 |
+ UPDATE_REG(0x202, IF); |
|
| 811 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 812 |
+ } |
|
| 803 | 813 |
|
| 804 |
- if (((DM0CNT_H >> 5) & 3) == 3) |
|
| 805 |
- dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 814 |
+ if (((DM0CNT_H >> 5) & 3) == 3) |
|
| 815 |
+ dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 806 | 816 |
|
| 807 |
- if (!(DM0CNT_H & 0x0200) || !reason) |
|
| 808 |
- {
|
|
| 809 |
- DM0CNT_H &= 0x7FFF; |
|
| 810 |
- UPDATE_REG(0xBA, DM0CNT_H); |
|
| 811 |
- } |
|
| 817 |
+ if (!(DM0CNT_H & 0x0200) || !reason) |
|
| 818 |
+ {
|
|
| 819 |
+ DM0CNT_H &= 0x7FFF; |
|
| 820 |
+ UPDATE_REG(0xBA, DM0CNT_H); |
|
| 812 | 821 |
} |
| 813 | 822 |
} |
| 814 | 823 |
|
| 815 | 824 |
// DMA 1 |
| 816 |
- if ((DM1CNT_H & 0x8000) && (dmamask & 2)) |
|
| 825 |
+ if ((DM1CNT_H & 0x8000) && (dmamask & 2) && ((DM1CNT_H >> 12) & 3) == reason) |
|
| 817 | 826 |
{
|
| 818 |
- if (((DM1CNT_H >> 12) & 3) == reason) |
|
| 827 |
+ uint32_t sourceIncrement = 4; |
|
| 828 |
+ uint32_t destIncrement = 4; |
|
| 829 |
+ switch ((DM1CNT_H >> 7) & 3) |
|
| 819 | 830 |
{
|
| 820 |
- uint32_t sourceIncrement = 4; |
|
| 821 |
- uint32_t destIncrement = 4; |
|
| 822 |
- switch ((DM1CNT_H >> 7) & 3) |
|
| 823 |
- {
|
|
| 824 |
- case 1: |
|
| 825 |
- sourceIncrement = static_cast<uint32_t>(-4); |
|
| 826 |
- break; |
|
| 827 |
- case 2: |
|
| 828 |
- sourceIncrement = 0; |
|
| 829 |
- } |
|
| 830 |
- switch ((DM1CNT_H >> 5) & 3) |
|
| 831 |
- {
|
|
| 832 |
- case 1: |
|
| 833 |
- destIncrement = static_cast<uint32_t>(-4); |
|
| 834 |
- break; |
|
| 835 |
- case 2: |
|
| 836 |
- destIncrement = 0; |
|
| 837 |
- } |
|
| 838 |
- if (reason == 3) |
|
| 839 |
- doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, 0x0400); |
|
| 840 |
- else |
|
| 841 |
- doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, DM1CNT_L ? DM1CNT_L : 0x4000, DM1CNT_H & 0x0400); |
|
| 831 |
+ case 1: |
|
| 832 |
+ sourceIncrement = static_cast<uint32_t>(-4); |
|
| 833 |
+ break; |
|
| 834 |
+ case 2: |
|
| 835 |
+ sourceIncrement = 0; |
|
| 836 |
+ } |
|
| 837 |
+ switch ((DM1CNT_H >> 5) & 3) |
|
| 838 |
+ {
|
|
| 839 |
+ case 1: |
|
| 840 |
+ destIncrement = static_cast<uint32_t>(-4); |
|
| 841 |
+ break; |
|
| 842 |
+ case 2: |
|
| 843 |
+ destIncrement = 0; |
|
| 844 |
+ } |
|
| 845 |
+ if (reason == 3) |
|
| 846 |
+ doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, 0x0400); |
|
| 847 |
+ else |
|
| 848 |
+ doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, DM1CNT_L ? DM1CNT_L : 0x4000, DM1CNT_H & 0x0400); |
|
| 842 | 849 |
|
| 843 |
- if (DM1CNT_H & 0x4000) |
|
| 844 |
- {
|
|
| 845 |
- IF |= 0x0200; |
|
| 846 |
- UPDATE_REG(0x202, IF); |
|
| 847 |
- cpuNextEvent = cpuTotalTicks; |
|
| 848 |
- } |
|
| 850 |
+ if (DM1CNT_H & 0x4000) |
|
| 851 |
+ {
|
|
| 852 |
+ IF |= 0x0200; |
|
| 853 |
+ UPDATE_REG(0x202, IF); |
|
| 854 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 855 |
+ } |
|
| 849 | 856 |
|
| 850 |
- if (((DM1CNT_H >> 5) & 3) == 3) |
|
| 851 |
- dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 857 |
+ if (((DM1CNT_H >> 5) & 3) == 3) |
|
| 858 |
+ dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 852 | 859 |
|
| 853 |
- if (!(DM1CNT_H & 0x0200) || !reason) |
|
| 854 |
- {
|
|
| 855 |
- DM1CNT_H &= 0x7FFF; |
|
| 856 |
- UPDATE_REG(0xC6, DM1CNT_H); |
|
| 857 |
- } |
|
| 860 |
+ if (!(DM1CNT_H & 0x0200) || !reason) |
|
| 861 |
+ {
|
|
| 862 |
+ DM1CNT_H &= 0x7FFF; |
|
| 863 |
+ UPDATE_REG(0xC6, DM1CNT_H); |
|
| 858 | 864 |
} |
| 859 | 865 |
} |
| 860 | 866 |
|
| 861 | 867 |
// DMA 2 |
| 862 |
- if ((DM2CNT_H & 0x8000) && (dmamask & 4)) |
|
| 868 |
+ if ((DM2CNT_H & 0x8000) && (dmamask & 4) && ((DM2CNT_H >> 12) & 3) == reason) |
|
| 863 | 869 |
{
|
| 864 |
- if (((DM2CNT_H >> 12) & 3) == reason) |
|
| 870 |
+ uint32_t sourceIncrement = 4; |
|
| 871 |
+ uint32_t destIncrement = 4; |
|
| 872 |
+ switch ((DM2CNT_H >> 7) & 3) |
|
| 865 | 873 |
{
|
| 866 |
- uint32_t sourceIncrement = 4; |
|
| 867 |
- uint32_t destIncrement = 4; |
|
| 868 |
- switch ((DM2CNT_H >> 7) & 3) |
|
| 869 |
- {
|
|
| 870 |
- case 1: |
|
| 871 |
- sourceIncrement = static_cast<uint32_t>(-4); |
|
| 872 |
- break; |
|
| 873 |
- case 2: |
|
| 874 |
- sourceIncrement = 0; |
|
| 875 |
- } |
|
| 876 |
- switch ((DM2CNT_H >> 5) & 3) |
|
| 877 |
- {
|
|
| 878 |
- case 1: |
|
| 879 |
- destIncrement = static_cast<uint32_t>(-4); |
|
| 880 |
- break; |
|
| 881 |
- case 2: |
|
| 882 |
- destIncrement = 0; |
|
| 883 |
- } |
|
| 884 |
- if (reason == 3) |
|
| 885 |
- doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, 0x0400); |
|
| 886 |
- else |
|
| 887 |
- doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, DM2CNT_L ? DM2CNT_L : 0x4000, DM2CNT_H & 0x0400); |
|
| 874 |
+ case 1: |
|
| 875 |
+ sourceIncrement = static_cast<uint32_t>(-4); |
|
| 876 |
+ break; |
|
| 877 |
+ case 2: |
|
| 878 |
+ sourceIncrement = 0; |
|
| 879 |
+ } |
|
| 880 |
+ switch ((DM2CNT_H >> 5) & 3) |
|
| 881 |
+ {
|
|
| 882 |
+ case 1: |
|
| 883 |
+ destIncrement = static_cast<uint32_t>(-4); |
|
| 884 |
+ break; |
|
| 885 |
+ case 2: |
|
| 886 |
+ destIncrement = 0; |
|
| 887 |
+ } |
|
| 888 |
+ if (reason == 3) |
|
| 889 |
+ doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, 0x0400); |
|
| 890 |
+ else |
|
| 891 |
+ doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, DM2CNT_L ? DM2CNT_L : 0x4000, DM2CNT_H & 0x0400); |
|
| 888 | 892 |
|
| 889 |
- if (DM2CNT_H & 0x4000) |
|
| 890 |
- {
|
|
| 891 |
- IF |= 0x0400; |
|
| 892 |
- UPDATE_REG(0x202, IF); |
|
| 893 |
- cpuNextEvent = cpuTotalTicks; |
|
| 894 |
- } |
|
| 893 |
+ if (DM2CNT_H & 0x4000) |
|
| 894 |
+ {
|
|
| 895 |
+ IF |= 0x0400; |
|
| 896 |
+ UPDATE_REG(0x202, IF); |
|
| 897 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 898 |
+ } |
|
| 895 | 899 |
|
| 896 |
- if (((DM2CNT_H >> 5) & 3) == 3) |
|
| 897 |
- dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 900 |
+ if (((DM2CNT_H >> 5) & 3) == 3) |
|
| 901 |
+ dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 898 | 902 |
|
| 899 |
- if (!(DM2CNT_H & 0x0200) || !reason) |
|
| 900 |
- {
|
|
| 901 |
- DM2CNT_H &= 0x7FFF; |
|
| 902 |
- UPDATE_REG(0xD2, DM2CNT_H); |
|
| 903 |
- } |
|
| 903 |
+ if (!(DM2CNT_H & 0x0200) || !reason) |
|
| 904 |
+ {
|
|
| 905 |
+ DM2CNT_H &= 0x7FFF; |
|
| 906 |
+ UPDATE_REG(0xD2, DM2CNT_H); |
|
| 904 | 907 |
} |
| 905 | 908 |
} |
| 906 | 909 |
|
| 907 | 910 |
// DMA 3 |
| 908 |
- if ((DM3CNT_H & 0x8000) && (dmamask & 8)) |
|
| 911 |
+ if ((DM3CNT_H & 0x8000) && (dmamask & 8) && ((DM3CNT_H >> 12) & 3) == reason) |
|
| 909 | 912 |
{
|
| 910 |
- if (((DM3CNT_H >> 12) & 3) == reason) |
|
| 913 |
+ uint32_t sourceIncrement = 4; |
|
| 914 |
+ uint32_t destIncrement = 4; |
|
| 915 |
+ switch ((DM3CNT_H >> 7) & 3) |
|
| 911 | 916 |
{
|
| 912 |
- uint32_t sourceIncrement = 4; |
|
| 913 |
- uint32_t destIncrement = 4; |
|
| 914 |
- switch ((DM3CNT_H >> 7) & 3) |
|
| 915 |
- {
|
|
| 916 |
- case 1: |
|
| 917 |
- sourceIncrement = static_cast<uint32_t>(-4); |
|
| 918 |
- break; |
|
| 919 |
- case 2: |
|
| 920 |
- sourceIncrement = 0; |
|
| 921 |
- } |
|
| 922 |
- switch ((DM3CNT_H >> 5) & 3) |
|
| 923 |
- {
|
|
| 924 |
- case 1: |
|
| 925 |
- destIncrement = static_cast<uint32_t>(-4); |
|
| 926 |
- break; |
|
| 927 |
- case 2: |
|
| 928 |
- destIncrement = 0; |
|
| 929 |
- } |
|
| 930 |
- doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, DM3CNT_L ? DM3CNT_L : 0x10000, DM3CNT_H & 0x0400); |
|
| 931 |
- |
|
| 932 |
- if (DM3CNT_H & 0x4000) |
|
| 933 |
- {
|
|
| 934 |
- IF |= 0x0800; |
|
| 935 |
- UPDATE_REG(0x202, IF); |
|
| 936 |
- cpuNextEvent = cpuTotalTicks; |
|
| 937 |
- } |
|
| 917 |
+ case 1: |
|
| 918 |
+ sourceIncrement = static_cast<uint32_t>(-4); |
|
| 919 |
+ break; |
|
| 920 |
+ case 2: |
|
| 921 |
+ sourceIncrement = 0; |
|
| 922 |
+ } |
|
| 923 |
+ switch ((DM3CNT_H >> 5) & 3) |
|
| 924 |
+ {
|
|
| 925 |
+ case 1: |
|
| 926 |
+ destIncrement = static_cast<uint32_t>(-4); |
|
| 927 |
+ break; |
|
| 928 |
+ case 2: |
|
| 929 |
+ destIncrement = 0; |
|
| 930 |
+ } |
|
| 931 |
+ doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, DM3CNT_L ? DM3CNT_L : 0x10000, DM3CNT_H & 0x0400); |
|
| 938 | 932 |
|
| 939 |
- if (((DM3CNT_H >> 5) & 3) == 3) |
|
| 940 |
- dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 933 |
+ if (DM3CNT_H & 0x4000) |
|
| 934 |
+ {
|
|
| 935 |
+ IF |= 0x0800; |
|
| 936 |
+ UPDATE_REG(0x202, IF); |
|
| 937 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 938 |
+ } |
|
| 941 | 939 |
|
| 942 |
- if (!(DM3CNT_H & 0x0200) || !reason) |
|
| 943 |
- {
|
|
| 944 |
- DM3CNT_H &= 0x7FFF; |
|
| 945 |
- UPDATE_REG(0xDE, DM3CNT_H); |
|
| 946 |
- } |
|
| 940 |
+ if (((DM3CNT_H >> 5) & 3) == 3) |
|
| 941 |
+ dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 942 |
+ |
|
| 943 |
+ if (!(DM3CNT_H & 0x0200) || !reason) |
|
| 944 |
+ {
|
|
| 945 |
+ DM3CNT_H &= 0x7FFF; |
|
| 946 |
+ UPDATE_REG(0xDE, DM3CNT_H); |
|
| 947 | 947 |
} |
| 948 | 948 |
} |
| 949 | 949 |
} |
| ... | ... |
@@ -953,41 +953,41 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 953 | 953 |
switch (address) |
| 954 | 954 |
{
|
| 955 | 955 |
case 0x00: |
| 956 |
- {
|
|
| 957 |
- if ((value & 7) > 5) |
|
| 958 |
- // display modes above 0-5 are prohibited |
|
| 959 |
- DISPCNT = value & 7; |
|
| 960 |
- bool change = !!((DISPCNT ^ value) & 0x80); |
|
| 961 |
- uint16_t changeBGon = (~DISPCNT & value) & 0x0F00; // these layers are being activated |
|
| 956 |
+ {
|
|
| 957 |
+ if ((value & 7) > 5) |
|
| 958 |
+ // display modes above 0-5 are prohibited |
|
| 959 |
+ DISPCNT = value & 7; |
|
| 960 |
+ bool change = !!((DISPCNT ^ value) & 0x80); |
|
| 961 |
+ uint16_t changeBGon = (~DISPCNT & value) & 0x0F00; // these layers are being activated |
|
| 962 | 962 |
|
| 963 |
- DISPCNT = value & 0xFFF7; // bit 3 can only be accessed by the BIOS to enable GBC mode |
|
| 964 |
- UPDATE_REG(0x00, DISPCNT); |
|
| 963 |
+ DISPCNT = value & 0xFFF7; // bit 3 can only be accessed by the BIOS to enable GBC mode |
|
| 964 |
+ UPDATE_REG(0x00, DISPCNT); |
|
| 965 | 965 |
|
| 966 |
- if (changeBGon) |
|
| 967 |
- {
|
|
| 968 |
- layerEnableDelay = 4; |
|
| 969 |
- layerEnable = layerSettings & value & ~changeBGon; |
|
| 970 |
- } |
|
| 971 |
- else |
|
| 972 |
- {
|
|
| 973 |
- layerEnable = layerSettings & value; |
|
| 974 |
- //CPUUpdateTicks(); |
|
| 975 |
- } |
|
| 966 |
+ if (changeBGon) |
|
| 967 |
+ {
|
|
| 968 |
+ layerEnableDelay = 4; |
|
| 969 |
+ layerEnable = layerSettings & value & ~changeBGon; |
|
| 970 |
+ } |
|
| 971 |
+ else |
|
| 972 |
+ {
|
|
| 973 |
+ layerEnable = layerSettings & value; |
|
| 974 |
+ // CPUUpdateTicks(); |
|
| 975 |
+ } |
|
| 976 | 976 |
|
| 977 |
- if (change && !(value & 0x80)) |
|
| 978 |
- {
|
|
| 979 |
- if (!(DISPSTAT & 1)) |
|
| 977 |
+ if (change && !(value & 0x80)) |
|
| 980 | 978 |
{
|
| 981 |
- lcdTicks = 1008; |
|
| 982 |
- //VCOUNT = 0; |
|
| 983 |
- //UPDATE_REG(0x06, VCOUNT); |
|
| 984 |
- DISPSTAT &= 0xFFFC; |
|
| 985 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 986 |
- CPUCompareVCOUNT(); |
|
| 979 |
+ if (!(DISPSTAT & 1)) |
|
| 980 |
+ {
|
|
| 981 |
+ //lcdTicks = 1008; |
|
| 982 |
+ //VCOUNT = 0; |
|
| 983 |
+ //UPDATE_REG(0x06, VCOUNT); |
|
| 984 |
+ DISPSTAT &= 0xFFFC; |
|
| 985 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 986 |
+ CPUCompareVCOUNT(); |
|
| 987 |
+ } |
|
| 987 | 988 |
} |
| 988 | 989 |
} |
| 989 | 990 |
break; |
| 990 |
- } |
|
| 991 | 991 |
case 0x04: |
| 992 | 992 |
DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7); |
| 993 | 993 |
UPDATE_REG(0x04, DISPSTAT); |
| ... | ... |
@@ -1199,21 +1199,21 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 1199 | 1199 |
UPDATE_REG(0xB8, 0); |
| 1200 | 1200 |
break; |
| 1201 | 1201 |
case 0xBA: |
| 1202 |
- {
|
|
| 1203 |
- bool start = !!((DM0CNT_H ^ value) & 0x8000); |
|
| 1204 |
- value &= 0xF7E0; |
|
| 1202 |
+ {
|
|
| 1203 |
+ bool start = !!((DM0CNT_H ^ value) & 0x8000); |
|
| 1204 |
+ value &= 0xF7E0; |
|
| 1205 | 1205 |
|
| 1206 |
- DM0CNT_H = value; |
|
| 1207 |
- UPDATE_REG(0xBA, DM0CNT_H); |
|
| 1206 |
+ DM0CNT_H = value; |
|
| 1207 |
+ UPDATE_REG(0xBA, DM0CNT_H); |
|
| 1208 | 1208 |
|
| 1209 |
- if (start && (value & 0x8000)) |
|
| 1210 |
- {
|
|
| 1211 |
- dma0Source = DM0SAD_L | (DM0SAD_H << 16); |
|
| 1212 |
- dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 1213 |
- CPUCheckDMA(0, 1); |
|
| 1209 |
+ if (start && (value & 0x8000)) |
|
| 1210 |
+ {
|
|
| 1211 |
+ dma0Source = DM0SAD_L | (DM0SAD_H << 16); |
|
| 1212 |
+ dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 1213 |
+ CPUCheckDMA(0, 1); |
|
| 1214 |
+ } |
|
| 1214 | 1215 |
} |
| 1215 | 1216 |
break; |
| 1216 |
- } |
|
| 1217 | 1217 |
case 0xBC: |
| 1218 | 1218 |
DM1SAD_L = value; |
| 1219 | 1219 |
UPDATE_REG(0xBC, DM1SAD_L); |
| ... | ... |
@@ -1235,21 +1235,21 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 1235 | 1235 |
UPDATE_REG(0xC4, 0); |
| 1236 | 1236 |
break; |
| 1237 | 1237 |
case 0xC6: |
| 1238 |
- {
|
|
| 1239 |
- bool start = !!((DM1CNT_H ^ value) & 0x8000); |
|
| 1240 |
- value &= 0xF7E0; |
|
| 1238 |
+ {
|
|
| 1239 |
+ bool start = !!((DM1CNT_H ^ value) & 0x8000); |
|
| 1240 |
+ value &= 0xF7E0; |
|
| 1241 | 1241 |
|
| 1242 |
- DM1CNT_H = value; |
|
| 1243 |
- UPDATE_REG(0xC6, DM1CNT_H); |
|
| 1242 |
+ DM1CNT_H = value; |
|
| 1243 |
+ UPDATE_REG(0xC6, DM1CNT_H); |
|
| 1244 | 1244 |
|
| 1245 |
- if (start && (value & 0x8000)) |
|
| 1246 |
- {
|
|
| 1247 |
- dma1Source = DM1SAD_L | (DM1SAD_H << 16); |
|
| 1248 |
- dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 1249 |
- CPUCheckDMA(0, 2); |
|
| 1245 |
+ if (start && (value & 0x8000)) |
|
| 1246 |
+ {
|
|
| 1247 |
+ dma1Source = DM1SAD_L | (DM1SAD_H << 16); |
|
| 1248 |
+ dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 1249 |
+ CPUCheckDMA(0, 2); |
|
| 1250 |
+ } |
|
| 1250 | 1251 |
} |
| 1251 | 1252 |
break; |
| 1252 |
- } |
|
| 1253 | 1253 |
case 0xC8: |
| 1254 | 1254 |
DM2SAD_L = value; |
| 1255 | 1255 |
UPDATE_REG(0xC8, DM2SAD_L); |
| ... | ... |
@@ -1271,21 +1271,21 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 1271 | 1271 |
UPDATE_REG(0xD0, 0); |
| 1272 | 1272 |
break; |
| 1273 | 1273 |
case 0xD2: |
| 1274 |
- {
|
|
| 1275 |
- bool start = !!((DM2CNT_H ^ value) & 0x8000); |
|
| 1276 |
- value &= 0xF7E0; |
|
| 1274 |
+ {
|
|
| 1275 |
+ bool start = !!((DM2CNT_H ^ value) & 0x8000); |
|
| 1276 |
+ value &= 0xF7E0; |
|
| 1277 | 1277 |
|
| 1278 |
- DM2CNT_H = value; |
|
| 1279 |
- UPDATE_REG(0xD2, DM2CNT_H); |
|
| 1278 |
+ DM2CNT_H = value; |
|
| 1279 |
+ UPDATE_REG(0xD2, DM2CNT_H); |
|
| 1280 | 1280 |
|
| 1281 |
- if (start && (value & 0x8000)) |
|
| 1282 |
- {
|
|
| 1283 |
- dma2Source = DM2SAD_L | (DM2SAD_H << 16); |
|
| 1284 |
- dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 1285 |
- CPUCheckDMA(0, 4); |
|
| 1281 |
+ if (start && (value & 0x8000)) |
|
| 1282 |
+ {
|
|
| 1283 |
+ dma2Source = DM2SAD_L | (DM2SAD_H << 16); |
|
| 1284 |
+ dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 1285 |
+ CPUCheckDMA(0, 4); |
|
| 1286 |
+ } |
|
| 1286 | 1287 |
} |
| 1287 | 1288 |
break; |
| 1288 |
- } |
|
| 1289 | 1289 |
case 0xD4: |
| 1290 | 1290 |
DM3SAD_L = value; |
| 1291 | 1291 |
UPDATE_REG(0xD4, DM3SAD_L); |
| ... | ... |
@@ -1307,21 +1307,21 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 1307 | 1307 |
UPDATE_REG(0xDC, 0); |
| 1308 | 1308 |
break; |
| 1309 | 1309 |
case 0xDE: |
| 1310 |
- {
|
|
| 1311 |
- bool start = !!((DM3CNT_H ^ value) & 0x8000); |
|
| 1312 |
- value &= 0xFFE0; |
|
| 1310 |
+ {
|
|
| 1311 |
+ bool start = !!((DM3CNT_H ^ value) & 0x8000); |
|
| 1312 |
+ value &= 0xFFE0; |
|
| 1313 | 1313 |
|
| 1314 |
- DM3CNT_H = value; |
|
| 1315 |
- UPDATE_REG(0xDE, DM3CNT_H); |
|
| 1314 |
+ DM3CNT_H = value; |
|
| 1315 |
+ UPDATE_REG(0xDE, DM3CNT_H); |
|
| 1316 | 1316 |
|
| 1317 |
- if (start && (value & 0x8000)) |
|
| 1318 |
- {
|
|
| 1319 |
- dma3Source = DM3SAD_L | (DM3SAD_H << 16); |
|
| 1320 |
- dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 1321 |
- CPUCheckDMA(0, 8); |
|
| 1317 |
+ if (start && (value & 0x8000)) |
|
| 1318 |
+ {
|
|
| 1319 |
+ dma3Source = DM3SAD_L | (DM3SAD_H << 16); |
|
| 1320 |
+ dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 1321 |
+ CPUCheckDMA(0, 8); |
|
| 1322 |
+ } |
|
| 1322 | 1323 |
} |
| 1323 | 1324 |
break; |
| 1324 |
- } |
|
| 1325 | 1325 |
case 0x100: |
| 1326 | 1326 |
timer0Reload = value; |
| 1327 | 1327 |
break; |
| ... | ... |
@@ -1396,7 +1396,6 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 1396 | 1396 |
busPrefetch = false; |
| 1397 | 1397 |
busPrefetchCount = 0; |
| 1398 | 1398 |
UPDATE_REG(0x204, value & 0x7FFF); |
| 1399 |
- |
|
| 1400 | 1399 |
break; |
| 1401 | 1400 |
case 0x208: |
| 1402 | 1401 |
IME = value & 1; |
| ... | ... |
@@ -1414,7 +1413,7 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 1414 | 1413 |
} |
| 1415 | 1414 |
} |
| 1416 | 1415 |
|
| 1417 |
-void applyTimer() |
|
| 1416 |
+static void applyTimer() |
|
| 1418 | 1417 |
{
|
| 1419 | 1418 |
if (timerOnOffDelay & 1) |
| 1420 | 1419 |
{
|
| ... | ... |
@@ -1478,7 +1477,6 @@ void applyTimer() |
| 1478 | 1477 |
} |
| 1479 | 1478 |
|
| 1480 | 1479 |
uint8_t cpuBitsSet[256]; |
| 1481 |
-uint8_t cpuLowestBitSet[256]; |
|
| 1482 | 1480 |
|
| 1483 | 1481 |
void CPUInit() |
| 1484 | 1482 |
{
|
| ... | ... |
@@ -1491,7 +1489,7 @@ void CPUInit() |
| 1491 | 1489 |
} |
| 1492 | 1490 |
#endif |
| 1493 | 1491 |
|
| 1494 |
- memcpy(&bios[0], &myROM[0], sizeof(myROM)); |
|
| 1492 |
+ memcpy(&bios[0], myROM, sizeof(myROM)); |
|
| 1495 | 1493 |
|
| 1496 | 1494 |
biosProtected[0] = 0x00; |
| 1497 | 1495 |
biosProtected[1] = 0xf0; |
| ... | ... |
@@ -1501,16 +1499,10 @@ void CPUInit() |
| 1501 | 1499 |
for (int i = 0; i < 256; ++i) |
| 1502 | 1500 |
{
|
| 1503 | 1501 |
int count = 0; |
| 1504 |
- int j; |
|
| 1505 |
- for (j = 0; j < 8; ++j) |
|
| 1502 |
+ for (int j = 0; j < 8; ++j) |
|
| 1506 | 1503 |
if (i & (1 << j)) |
| 1507 | 1504 |
++count; |
| 1508 | 1505 |
cpuBitsSet[i] = count; |
| 1509 |
- |
|
| 1510 |
- for (j = 0; j < 8; ++j) |
|
| 1511 |
- if (i & (1 << j)) |
|
| 1512 |
- break; |
|
| 1513 |
- cpuLowestBitSet[i] = j; |
|
| 1514 | 1506 |
} |
| 1515 | 1507 |
|
| 1516 | 1508 |
std::fill(&ioReadable[0], &ioReadable[0x304], true); |
| ... | ... |
@@ -1658,7 +1650,6 @@ void CPUReset() |
| 1658 | 1650 |
|
| 1659 | 1651 |
// reset internal state |
| 1660 | 1652 |
holdState = false; |
| 1661 |
- holdType = 0; |
|
| 1662 | 1653 |
|
| 1663 | 1654 |
biosProtected[0] = 0x00; |
| 1664 | 1655 |
biosProtected[1] = 0xf0; |
| ... | ... |
@@ -1728,10 +1719,12 @@ void CPUReset() |
| 1728 | 1719 |
|
| 1729 | 1720 |
ARM_PREFETCH(); |
| 1730 | 1721 |
|
| 1722 |
+ cpuDmaHack = false; |
|
| 1723 |
+ |
|
| 1731 | 1724 |
SWITicks = 0; |
| 1732 | 1725 |
} |
| 1733 | 1726 |
|
| 1734 |
-void CPUInterrupt() |
|
| 1727 |
+static void CPUInterrupt() |
|
| 1735 | 1728 |
{
|
| 1736 | 1729 |
uint32_t PC = reg[15].I; |
| 1737 | 1730 |
bool savedState = armState; |
| ... | ... |
@@ -1747,7 +1740,7 @@ void CPUInterrupt() |
| 1747 | 1740 |
reg[15].I += 4; |
| 1748 | 1741 |
ARM_PREFETCH(); |
| 1749 | 1742 |
|
| 1750 |
- //if(!holdState) |
|
| 1743 |
+ //if (!holdState) |
|
| 1751 | 1744 |
biosProtected[0] = 0x02; |
| 1752 | 1745 |
biosProtected[1] = 0xc0; |
| 1753 | 1746 |
biosProtected[2] = 0x5e; |
| ... | ... |
@@ -1801,7 +1794,6 @@ void CPULoop(int ticks) |
| 1801 | 1794 |
cpuTotalTicks = 0; |
| 1802 | 1795 |
|
| 1803 | 1796 |
updateLoop: |
| 1804 |
- |
|
| 1805 | 1797 |
if (IRQTicks) |
| 1806 | 1798 |
{
|
| 1807 | 1799 |
IRQTicks -= clockTicks; |
| ... | ... |
@@ -1837,7 +1829,7 @@ void CPULoop(int ticks) |
| 1837 | 1829 |
} |
| 1838 | 1830 |
} |
| 1839 | 1831 |
|
| 1840 |
- if (VCOUNT >= 228) //Reaching last line |
|
| 1832 |
+ if (VCOUNT > 227) //Reaching last line |
|
| 1841 | 1833 |
{
|
| 1842 | 1834 |
DISPSTAT &= 0xFFFC; |
| 1843 | 1835 |
UPDATE_REG(0x04, DISPSTAT); |
| ... | ... |
@@ -1858,10 +1850,6 @@ void CPULoop(int ticks) |
| 1858 | 1850 |
DISPSTAT &= 0xFFFD; |
| 1859 | 1851 |
if (VCOUNT == 160) |
| 1860 | 1852 |
{
|
| 1861 |
- ++count; |
|
| 1862 |
- if (count == 60) |
|
| 1863 |
- count = 0; |
|
| 1864 |
- |
|
| 1865 | 1853 |
DISPSTAT |= 1; |
| 1866 | 1854 |
DISPSTAT &= 0xFFFD; |
| 1867 | 1855 |
UPDATE_REG(0x04, DISPSTAT); |
| ... | ... |
@@ -2070,7 +2058,6 @@ void CPULoop(int ticks) |
| 2070 | 2058 |
intState = false; |
| 2071 | 2059 |
holdState = false; |
| 2072 | 2060 |
stopState = false; |
| 2073 |
- holdType = 0; |
|
| 2074 | 2061 |
} |
| 2075 | 2062 |
} |
| 2076 | 2063 |
else |
| ... | ... |
@@ -2087,7 +2074,6 @@ void CPULoop(int ticks) |
| 2087 | 2074 |
CPUInterrupt(); |
| 2088 | 2075 |
holdState = false; |
| 2089 | 2076 |
stopState = false; |
| 2090 |
- holdType = 0; |
|
| 2091 | 2077 |
} |
| 2092 | 2078 |
} |
| 2093 | 2079 |
|
| ... | ... |
@@ -11,10 +11,6 @@ |
| 11 | 11 |
|
| 12 | 12 |
extern int mapgsf(uint8_t *a, int l, int &s); |
| 13 | 13 |
|
| 14 |
-#ifdef __GNUC__ |
|
| 15 |
-#define _stricmp strcasecmp |
|
| 16 |
-#endif |
|
| 17 |
- |
|
| 18 | 14 |
int SWITicks = 0; |
| 19 | 15 |
static int IRQTicks = 0; |
| 20 | 16 |
|
| ... | ... |
@@ -306,8 +302,7 @@ int CPULoadRom() |
| 306 | 302 |
mapgsf(rom, 0x2000000, romSize); |
| 307 | 303 |
|
| 308 | 304 |
uint16_t *temp = reinterpret_cast<uint16_t *>(rom + ((romSize + 1) & ~1)); |
| 309 |
- int i; |
|
| 310 |
- for (i = (romSize + 1) & ~1; i < 0x2000000; i += 2) |
|
| 305 |
+ for (int i = (romSize + 1) & ~1; i < 0x2000000; i += 2) |
|
| 311 | 306 |
{
|
| 312 | 307 |
WRITE16LE(temp, (i >> 1) & 0xFFFF); |
| 313 | 308 |
++temp; |
| ... | ... |
@@ -498,9 +493,6 @@ void CPUSoftwareInterrupt(int comment) |
| 498 | 493 |
comment >>= 16; |
| 499 | 494 |
if (comment == 0xfa) |
| 500 | 495 |
return; |
| 501 |
- // This would be correct, but it causes problems if uncommented |
|
| 502 |
- //else |
|
| 503 |
- //biosProtected = 0xe3a02004; |
|
| 504 | 496 |
|
| 505 | 497 |
switch (comment) |
| 506 | 498 |
{
|
| ... | ... |
@@ -543,7 +535,7 @@ void CPUSoftwareInterrupt(int comment) |
| 543 | 535 |
if ((reg[2].I >> 26) & 1) |
| 544 | 536 |
SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); |
| 545 | 537 |
else |
| 546 |
- SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * (len); |
|
| 538 |
+ SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 547 | 539 |
} |
| 548 | 540 |
else |
| 549 | 541 |
{
|
| ... | ... |
@@ -638,7 +630,7 @@ void CPUSoftwareInterrupt(int comment) |
| 638 | 630 |
{
|
| 639 | 631 |
uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
| 640 | 632 |
if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
| 641 |
- SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF]<<1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 633 |
+ SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 642 | 634 |
BIOS_Diff8bitUnFilterVram(); |
| 643 | 635 |
break; |
| 644 | 636 |
} |
| ... | ... |
@@ -786,8 +778,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 786 | 778 |
uint32_t destIncrement = 4; |
| 787 | 779 |
switch ((DM0CNT_H >> 7) & 3) |
| 788 | 780 |
{
|
| 789 |
- case 0: |
|
| 790 |
- break; |
|
| 791 | 781 |
case 1: |
| 792 | 782 |
sourceIncrement = static_cast<uint32_t>(-4); |
| 793 | 783 |
break; |
| ... | ... |
@@ -796,8 +786,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 796 | 786 |
} |
| 797 | 787 |
switch ((DM0CNT_H >> 5) & 3) |
| 798 | 788 |
{
|
| 799 |
- case 0: |
|
| 800 |
- break; |
|
| 801 | 789 |
case 1: |
| 802 | 790 |
destIncrement = static_cast<uint32_t>(-4); |
| 803 | 791 |
break; |
| ... | ... |
@@ -833,8 +821,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 833 | 821 |
uint32_t destIncrement = 4; |
| 834 | 822 |
switch ((DM1CNT_H >> 7) & 3) |
| 835 | 823 |
{
|
| 836 |
- case 0: |
|
| 837 |
- break; |
|
| 838 | 824 |
case 1: |
| 839 | 825 |
sourceIncrement = static_cast<uint32_t>(-4); |
| 840 | 826 |
break; |
| ... | ... |
@@ -843,8 +829,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 843 | 829 |
} |
| 844 | 830 |
switch ((DM1CNT_H >> 5) & 3) |
| 845 | 831 |
{
|
| 846 |
- case 0: |
|
| 847 |
- break; |
|
| 848 | 832 |
case 1: |
| 849 | 833 |
destIncrement = static_cast<uint32_t>(-4); |
| 850 | 834 |
break; |
| ... | ... |
@@ -883,8 +867,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 883 | 867 |
uint32_t destIncrement = 4; |
| 884 | 868 |
switch ((DM2CNT_H >> 7) & 3) |
| 885 | 869 |
{
|
| 886 |
- case 0: |
|
| 887 |
- break; |
|
| 888 | 870 |
case 1: |
| 889 | 871 |
sourceIncrement = static_cast<uint32_t>(-4); |
| 890 | 872 |
break; |
| ... | ... |
@@ -893,8 +875,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 893 | 875 |
} |
| 894 | 876 |
switch ((DM2CNT_H >> 5) & 3) |
| 895 | 877 |
{
|
| 896 |
- case 0: |
|
| 897 |
- break; |
|
| 898 | 878 |
case 1: |
| 899 | 879 |
destIncrement = static_cast<uint32_t>(-4); |
| 900 | 880 |
break; |
| ... | ... |
@@ -933,8 +913,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 933 | 913 |
uint32_t destIncrement = 4; |
| 934 | 914 |
switch ((DM3CNT_H >> 7) & 3) |
| 935 | 915 |
{
|
| 936 |
- case 0: |
|
| 937 |
- break; |
|
| 938 | 916 |
case 1: |
| 939 | 917 |
sourceIncrement = static_cast<uint32_t>(-4); |
| 940 | 918 |
break; |
| ... | ... |
@@ -943,8 +921,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 943 | 921 |
} |
| 944 | 922 |
switch ((DM3CNT_H >> 5) & 3) |
| 945 | 923 |
{
|
| 946 |
- case 0: |
|
| 947 |
- break; |
|
| 948 | 924 |
case 1: |
| 949 | 925 |
destIncrement = static_cast<uint32_t>(-4); |
| 950 | 926 |
break; |
| ... | ... |
@@ -952,6 +928,7 @@ void CPUCheckDMA(int reason, int dmamask) |
| 952 | 928 |
destIncrement = 0; |
| 953 | 929 |
} |
| 954 | 930 |
doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, DM3CNT_L ? DM3CNT_L : 0x10000, DM3CNT_H & 0x0400); |
| 931 |
+ |
|
| 955 | 932 |
if (DM3CNT_H & 0x4000) |
| 956 | 933 |
{
|
| 957 | 934 |
IF |= 0x0800; |
| ... | ... |
@@ -1002,6 +979,8 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 1002 | 979 |
if (!(DISPSTAT & 1)) |
| 1003 | 980 |
{
|
| 1004 | 981 |
lcdTicks = 1008; |
| 982 |
+ //VCOUNT = 0; |
|
| 983 |
+ //UPDATE_REG(0x06, VCOUNT); |
|
| 1005 | 984 |
DISPSTAT &= 0xFFFC; |
| 1006 | 985 |
UPDATE_REG(0x04, DISPSTAT); |
| 1007 | 986 |
CPUCompareVCOUNT(); |
| ... | ... |
@@ -1085,7 +1064,7 @@ void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 1085 | 1064 |
UPDATE_REG(0x28, BG2X_L); |
| 1086 | 1065 |
break; |
| 1087 | 1066 |
case 0x2A: |
| 1088 |
- BG2X_H = (value & 0xFFF); |
|
| 1067 |
+ BG2X_H = value & 0xFFF; |
|
| 1089 | 1068 |
UPDATE_REG(0x2A, BG2X_H); |
| 1090 | 1069 |
break; |
| 1091 | 1070 |
case 0x2C: |
| ... | ... |
@@ -1476,7 +1455,7 @@ void applyTimer() |
| 1476 | 1455 |
timer2Ticks = (0x10000 - TM2D) << timer2ClockReload; |
| 1477 | 1456 |
UPDATE_REG(0x108, TM2D); |
| 1478 | 1457 |
} |
| 1479 |
- timer2On = !(timer2Value & 0x80); |
|
| 1458 |
+ timer2On = !!(timer2Value & 0x80); |
|
| 1480 | 1459 |
TM2CNT = timer2Value & 0xC7; |
| 1481 | 1460 |
UPDATE_REG(0x10A, TM2CNT); |
| 1482 | 1461 |
} |
| ... | ... |
@@ -1511,7 +1490,8 @@ void CPUInit() |
| 1511 | 1490 |
cpuBiosSwapped = true; |
| 1512 | 1491 |
} |
| 1513 | 1492 |
#endif |
| 1514 |
- memcpy(&bios[0], myROM, sizeof(myROM)); |
|
| 1493 |
+ |
|
| 1494 |
+ memcpy(&bios[0], &myROM[0], sizeof(myROM)); |
|
| 1515 | 1495 |
|
| 1516 | 1496 |
biosProtected[0] = 0x00; |
| 1517 | 1497 |
biosProtected[1] = 0xf0; |
| ... | ... |
@@ -1724,7 +1704,7 @@ void CPUReset() |
| 1724 | 1704 |
map[2].mask = 0x3FFFF; |
| 1725 | 1705 |
map[3].address = &internalRAM[0]; |
| 1726 | 1706 |
map[3].mask = 0x7FFF; |
| 1727 |
- map[4].address = ioMem; |
|
| 1707 |
+ map[4].address = &ioMem[0]; |
|
| 1728 | 1708 |
map[4].mask = 0x3FF; |
| 1729 | 1709 |
map[5].address = &paletteRAM[0]; |
| 1730 | 1710 |
map[5].mask = 0x3FF; |
(As an aside, blargg's code style makes me go blarg myself.)
| ... | ... |
@@ -1,84 +1,43 @@ |
| 1 |
-#include <stdio.h> |
|
| 2 |
-#include <stdlib.h> |
|
| 3 |
-#include <memory.h> |
|
| 4 |
-#include <stdarg.h> |
|
| 5 |
-#include <string.h> |
|
| 1 |
+#include <algorithm> |
|
| 2 |
+#include <cstdlib> |
|
| 3 |
+#include <cstring> |
|
| 6 | 4 |
#include "GBA.h" |
| 7 | 5 |
#include "GBAcpu.h" |
| 8 | 6 |
#include "GBAinline.h" |
| 9 | 7 |
#include "Globals.h" |
| 10 |
-//#include "GBAGfx.h" |
|
| 11 |
-//#include "EEprom.h" |
|
| 12 |
-//#include "Flash.h" |
|
| 13 | 8 |
#include "Sound.h" |
| 14 |
-//#include "Sram.h" |
|
| 15 | 9 |
#include "bios.h" |
| 16 |
-//#include "Cheats.h" |
|
| 17 |
-//#include "../NLS.h" |
|
| 18 |
-//#include "elf.h" |
|
| 19 |
-//#include "../Util.h" |
|
| 20 | 10 |
#include "../common/Port.h" |
| 21 |
-//#include "../System.h" |
|
| 22 |
-//#include "agbprint.h" |
|
| 23 |
-//#include "GBALink.h" |
|
| 24 | 11 |
|
| 25 |
-extern int mapgsf(uint8_t* a, int l, int &s); |
|
| 26 |
- |
|
| 27 |
-#ifdef PROFILING |
|
| 28 |
-#include "prof/prof.h" |
|
| 29 |
-#endif |
|
| 12 |
+extern int mapgsf(uint8_t *a, int l, int &s); |
|
| 30 | 13 |
|
| 31 | 14 |
#ifdef __GNUC__ |
| 32 | 15 |
#define _stricmp strcasecmp |
| 33 | 16 |
#endif |
| 34 | 17 |
|
| 35 |
-extern int emulating; |
|
| 36 |
- |
|
| 37 | 18 |
int SWITicks = 0; |
| 38 |
-int IRQTicks = 0; |
|
| 19 |
+static int IRQTicks = 0; |
|
| 39 | 20 |
|
| 40 |
-uint32_t mastercode = 0; |
|
| 41 |
-int layerEnableDelay = 0; |
|
| 21 |
+static int layerEnableDelay = 0; |
|
| 42 | 22 |
bool busPrefetch = false; |
| 43 | 23 |
bool busPrefetchEnable = false; |
| 44 | 24 |
uint32_t busPrefetchCount = 0; |
| 45 |
-int cpuDmaTicksToUpdate = 0; |
|
| 46 |
-int cpuDmaCount = 0; |
|
| 47 |
-uint32_t cpuDmaLast = 0; |
|
| 48 |
-int dummyAddress = 0; |
|
| 25 |
+static int cpuDmaTicksToUpdate = 0; |
|
| 26 |
+static uint32_t cpuDmaLast = 0; |
|
| 27 |
+static int dummyAddress = 0; |
|
| 49 | 28 |
|
| 50 |
-bool cpuBreakLoop = false; |
|
| 51 | 29 |
int cpuNextEvent = 0; |
| 52 | 30 |
|
| 53 |
-int gbaSaveType = 0; // used to remember the save type on reset |
|
| 54 |
-bool intState = false; |
|
| 31 |
+static bool intState = false; |
|
| 55 | 32 |
bool stopState = false; |
| 56 | 33 |
bool holdState = false; |
| 57 | 34 |
int holdType = 0; |
| 58 |
-bool cpuSramEnabled = true; |
|
| 59 |
-bool cpuFlashEnabled = true; |
|
| 60 |
-bool cpuEEPROMEnabled = true; |
|
| 61 |
-bool cpuEEPROMSensorEnabled = false; |
|
| 62 | 35 |
|
| 63 | 36 |
uint32_t cpuPrefetch[2]; |
| 64 | 37 |
|
| 65 | 38 |
int cpuTotalTicks = 0; |
| 66 |
-#ifdef PROFILING |
|
| 67 |
-int profilingTicks = 0; |
|
| 68 |
-int profilingTicksReload = 0; |
|
| 69 |
-static profile_segment *profilSegment = NULL; |
|
| 70 |
-#endif |
|
| 71 | 39 |
|
| 72 |
-#ifdef BKPT_SUPPORT |
|
| 73 |
-uint8_t freezeWorkRAM[0x40000]; |
|
| 74 |
-uint8_t freezeInternalRAM[0x8000]; |
|
| 75 |
-uint8_t freezeVRAM[0x18000]; |
|
| 76 |
-uint8_t freezePRAM[0x400]; |
|
| 77 |
-uint8_t freezeOAM[0x400]; |
|
| 78 |
-bool debugger_last; |
|
| 79 |
-#endif |
|
| 80 |
- |
|
| 81 |
-int lcdTicks = (useBios && !skipBios) ? 1008 : 208; |
|
| 40 |
+int lcdTicks = 208; |
|
| 82 | 41 |
uint8_t timerOnOffDelay = 0; |
| 83 | 42 |
uint16_t timer0Value = 0; |
| 84 | 43 |
bool timer0On = false; |
| ... | ... |
@@ -108,52 +67,22 @@ uint32_t dma2Source = 0; |
| 108 | 67 |
uint32_t dma2Dest = 0; |
| 109 | 68 |
uint32_t dma3Source = 0; |
| 110 | 69 |
uint32_t dma3Dest = 0; |
| 111 |
-//void (*cpuSaveGameFunc)(u32,u8) = /*flashSaveDecide*/0; |
|
| 112 |
-//void (*renderLine)() = /*mode0RenderLine*/0; |
|
| 113 |
-bool fxOn = false; |
|
| 114 |
-bool windowOn = false; |
|
| 115 |
-int frameCount = 0; |
|
| 116 | 70 |
char buffer[1024]; |
| 117 |
-uint32_t lastTime = 0; |
|
| 118 | 71 |
int count = 0; |
| 119 | 72 |
|
| 120 |
-int capture = 0; |
|
| 121 |
-int capturePrevious = 0; |
|
| 122 |
-int captureNumber = 0; |
|
| 123 |
- |
|
| 124 |
-const int TIMER_TICKS[4] = {
|
|
| 125 |
- 0, |
|
| 126 |
- 6, |
|
| 127 |
- 8, |
|
| 128 |
- 10 |
|
| 129 |
-}; |
|
| 73 |
+static const int TIMER_TICKS[] = { 0, 6, 8, 10 };
|
|
| 130 | 74 |
|
| 131 |
-const uint32_t objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
|
|
| 132 |
-const uint8_t gamepakRamWaitState[4] = { 4, 3, 2, 8 };
|
|
| 133 |
-const uint8_t gamepakWaitState[4] = { 4, 3, 2, 8 };
|
|
| 134 |
-const uint8_t gamepakWaitState0[2] = { 2, 1 };
|
|
| 135 |
-const uint8_t gamepakWaitState1[2] = { 4, 1 };
|
|
| 136 |
-const uint8_t gamepakWaitState2[2] = { 8, 1 };
|
|
| 137 |
-const bool isInRom [16]= |
|
| 138 |
- { false, false, false, false, false, false, false, false,
|
|
| 139 |
- true, true, true, true, true, true, false, false }; |
|
| 140 |
- |
|
| 141 |
-uint8_t memoryWait[16] = |
|
| 142 |
- { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
|
|
| 143 |
-uint8_t memoryWait32[16] = |
|
| 144 |
- { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
|
|
| 145 |
-uint8_t memoryWaitSeq[16] = |
|
| 146 |
- { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
|
|
| 147 |
-uint8_t memoryWaitSeq32[16] = |
|
| 148 |
- { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
|
|
| 149 |
- |
|
| 150 |
-// The videoMemoryWait constants are used to add some waitstates |
|
| 151 |
-// if the opcode access video memory data outside of vblank/hblank |
|
| 152 |
-// It seems to happen on only one ticks for each pixel. |
|
| 153 |
-// Not used for now (too problematic with current code). |
|
| 154 |
-//const u8 videoMemoryWait[16] = |
|
| 155 |
-// {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
| 75 |
+const uint32_t objTilesAddress[] = { 0x010000, 0x014000, 0x014000 };
|
|
| 76 |
+static const uint8_t gamepakRamWaitState[] = { 4, 3, 2, 8 };
|
|
| 77 |
+static const uint8_t gamepakWaitState[] = { 4, 3, 2, 8 };
|
|
| 78 |
+static const uint8_t gamepakWaitState0[] = { 2, 1 };
|
|
| 79 |
+static const uint8_t gamepakWaitState1[] = { 4, 1 };
|
|
| 80 |
+static const uint8_t gamepakWaitState2[] = { 8, 1 };
|
|
| 156 | 81 |
|
| 82 |
+uint8_t memoryWait[] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
|
|
| 83 |
+uint8_t memoryWait32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
|
|
| 84 |
+uint8_t memoryWaitSeq[] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
|
|
| 85 |
+uint8_t memoryWaitSeq32[] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
|
|
| 157 | 86 |
|
| 158 | 87 |
uint8_t biosProtected[4]; |
| 159 | 88 |
|
| ... | ... |
@@ -161,3857 +90,2054 @@ uint8_t biosProtected[4]; |
| 161 | 90 |
bool cpuBiosSwapped = false; |
| 162 | 91 |
#endif |
| 163 | 92 |
|
| 164 |
-uint32_t myROM[] = {
|
|
| 165 |
-0xEA000006, |
|
| 166 |
-0xEA000093, |
|
| 167 |
-0xEA000006, |
|
| 168 |
-0x00000000, |
|
| 169 |
-0x00000000, |
|
| 170 |
-0x00000000, |
|
| 171 |
-0xEA000088, |
|
| 172 |
-0x00000000, |
|
| 173 |
-0xE3A00302, |
|
| 174 |
-0xE1A0F000, |
|
| 175 |
-0xE92D5800, |
|
| 176 |
-0xE55EC002, |
|
| 177 |
-0xE28FB03C, |
|
| 178 |
-0xE79BC10C, |
|
| 179 |
-0xE14FB000, |
|
| 180 |
-0xE92D0800, |
|
| 181 |
-0xE20BB080, |
|
| 182 |
-0xE38BB01F, |
|
| 183 |
-0xE129F00B, |
|
| 184 |
-0xE92D4004, |
|
| 185 |
-0xE1A0E00F, |
|
| 186 |
-0xE12FFF1C, |
|
| 187 |
-0xE8BD4004, |
|
| 188 |
-0xE3A0C0D3, |
|
| 189 |
-0xE129F00C, |
|
| 190 |
-0xE8BD0800, |
|
| 191 |
-0xE169F00B, |
|
| 192 |
-0xE8BD5800, |
|
| 193 |
-0xE1B0F00E, |
|
| 194 |
-0x0000009C, |
|
| 195 |
-0x0000009C, |
|
| 196 |
-0x0000009C, |
|
| 197 |
-0x0000009C, |
|
| 198 |
-0x000001F8, |
|
| 199 |
-0x000001F0, |
|
| 200 |
-0x000000AC, |
|
| 201 |
-0x000000A0, |
|
| 202 |
-0x000000FC, |
|
| 203 |
-0x00000168, |
|
| 204 |
-0xE12FFF1E, |
|
| 205 |
-0xE1A03000, |
|
| 206 |
-0xE1A00001, |
|
| 207 |
-0xE1A01003, |
|
| 208 |
-0xE2113102, |
|
| 209 |
-0x42611000, |
|
| 210 |
-0xE033C040, |
|
| 211 |
-0x22600000, |
|
| 212 |
-0xE1B02001, |
|
| 213 |
-0xE15200A0, |
|
| 214 |
-0x91A02082, |
|
| 215 |
-0x3AFFFFFC, |
|
| 216 |
-0xE1500002, |
|
| 217 |
-0xE0A33003, |
|
| 218 |
-0x20400002, |
|
| 219 |
-0xE1320001, |
|
| 220 |
-0x11A020A2, |
|
| 221 |
-0x1AFFFFF9, |
|
| 222 |
-0xE1A01000, |
|
| 223 |
-0xE1A00003, |
|
| 224 |
-0xE1B0C08C, |
|
| 225 |
-0x22600000, |
|
| 226 |
-0x42611000, |
|
| 227 |
-0xE12FFF1E, |
|
| 228 |
-0xE92D0010, |
|
| 229 |
-0xE1A0C000, |
|
| 230 |
-0xE3A01001, |
|
| 231 |
-0xE1500001, |
|
| 232 |
-0x81A000A0, |
|
| 233 |
-0x81A01081, |
|
| 234 |
-0x8AFFFFFB, |
|
| 235 |
-0xE1A0000C, |
|
| 236 |
-0xE1A04001, |
|
| 237 |
-0xE3A03000, |
|
| 238 |
-0xE1A02001, |
|
| 239 |
-0xE15200A0, |
|
| 240 |
-0x91A02082, |
|
| 241 |
-0x3AFFFFFC, |
|
| 242 |
-0xE1500002, |
|
| 243 |
-0xE0A33003, |
|
| 244 |
-0x20400002, |
|
| 245 |
-0xE1320001, |
|
| 246 |
-0x11A020A2, |
|
| 247 |
-0x1AFFFFF9, |
|
| 248 |
-0xE0811003, |
|
| 249 |
-0xE1B010A1, |
|
| 250 |
-0xE1510004, |
|
| 251 |
-0x3AFFFFEE, |
|
| 252 |
-0xE1A00004, |
|
| 253 |
-0xE8BD0010, |
|
| 254 |
-0xE12FFF1E, |
|
| 255 |
-0xE0010090, |
|
| 256 |
-0xE1A01741, |
|
| 257 |
-0xE2611000, |
|
| 258 |
-0xE3A030A9, |
|
| 259 |
-0xE0030391, |
|
| 260 |
-0xE1A03743, |
|
| 261 |
-0xE2833E39, |
|
| 262 |
-0xE0030391, |
|
| 263 |
-0xE1A03743, |
|
| 264 |
-0xE2833C09, |
|
| 265 |
-0xE283301C, |
|
| 266 |
-0xE0030391, |
|
| 267 |
-0xE1A03743, |
|
| 268 |
-0xE2833C0F, |
|
| 269 |
-0xE28330B6, |
|
| 270 |
-0xE0030391, |
|
| 271 |
-0xE1A03743, |
|
| 272 |
-0xE2833C16, |
|
| 273 |
-0xE28330AA, |
|
| 274 |
-0xE0030391, |
|
| 275 |
-0xE1A03743, |
|
| 276 |
-0xE2833A02, |
|
| 277 |
-0xE2833081, |
|
| 278 |
-0xE0030391, |
|
| 279 |
-0xE1A03743, |
|
| 280 |
-0xE2833C36, |
|
| 281 |
-0xE2833051, |
|
| 282 |
-0xE0030391, |
|
| 283 |
-0xE1A03743, |
|
| 284 |
-0xE2833CA2, |
|
| 285 |
-0xE28330F9, |
|
| 286 |
-0xE0000093, |
|
| 287 |
-0xE1A00840, |
|
| 288 |
-0xE12FFF1E, |
|
| 289 |
-0xE3A00001, |
|
| 290 |
-0xE3A01001, |
|
| 291 |
-0xE92D4010, |
|
| 292 |
-0xE3A03000, |
|
| 293 |
-0xE3A04001, |
|
| 294 |
-0xE3500000, |
|
| 295 |
-0x1B000004, |
|
| 296 |
-0xE5CC3301, |
|
| 297 |
-0xEB000002, |
|
| 298 |
-0x0AFFFFFC, |
|
| 299 |
-0xE8BD4010, |
|
| 300 |
-0xE12FFF1E, |
|
| 301 |
-0xE3A0C301, |
|
| 302 |
-0xE5CC3208, |
|
| 303 |
-0xE15C20B8, |
|
| 304 |
-0xE0110002, |
|
| 305 |
-0x10222000, |
|
| 306 |
-0x114C20B8, |
|
| 307 |
-0xE5CC4208, |
|
| 308 |
-0xE12FFF1E, |
|
| 309 |
-0xE92D500F, |
|
| 310 |
-0xE3A00301, |
|
| 311 |
-0xE1A0E00F, |
|
| 312 |
-0xE510F004, |
|
| 313 |
-0xE8BD500F, |
|
| 314 |
-0xE25EF004, |
|
| 315 |
-0xE59FD044, |
|
| 316 |
-0xE92D5000, |
|
| 317 |
-0xE14FC000, |
|
| 318 |
-0xE10FE000, |
|
| 319 |
-0xE92D5000, |
|
| 320 |
-0xE3A0C302, |
|
| 321 |
-0xE5DCE09C, |
|
| 322 |
-0xE35E00A5, |
|
| 323 |
-0x1A000004, |
|
| 324 |
-0x05DCE0B4, |
|
| 325 |
-0x021EE080, |
|
| 326 |
-0xE28FE004, |
|
| 327 |
-0x159FF018, |
|
| 328 |
-0x059FF018, |
|
| 329 |
-0xE59FD018, |
|
| 330 |
-0xE8BD5000, |
|
| 331 |
-0xE169F00C, |
|
| 332 |
-0xE8BD5000, |
|
| 333 |
-0xE25EF004, |
|
| 334 |
-0x03007FF0, |
|
| 335 |
-0x09FE2000, |
|
| 336 |
-0x09FFC000, |
|
| 337 |
-0x03007FE0 |
|
| 93 |
+uint32_t myROM[] = |
|
| 94 |
+{
|
|
| 95 |
+ 0xEA000006, |
|
| 96 |
+ 0xEA000093, |
|
| 97 |
+ 0xEA000006, |
|
| 98 |
+ 0x00000000, |
|
| 99 |
+ 0x00000000, |
|
| 100 |
+ 0x00000000, |
|
| 101 |
+ 0xEA000088, |
|
| 102 |
+ 0x00000000, |
|
| 103 |
+ 0xE3A00302, |
|
| 104 |
+ 0xE1A0F000, |
|
| 105 |
+ 0xE92D5800, |
|
| 106 |
+ 0xE55EC002, |
|
| 107 |
+ 0xE28FB03C, |
|
| 108 |
+ 0xE79BC10C, |
|
| 109 |
+ 0xE14FB000, |
|
| 110 |
+ 0xE92D0800, |
|
| 111 |
+ 0xE20BB080, |
|
| 112 |
+ 0xE38BB01F, |
|
| 113 |
+ 0xE129F00B, |
|
| 114 |
+ 0xE92D4004, |
|
| 115 |
+ 0xE1A0E00F, |
|
| 116 |
+ 0xE12FFF1C, |
|
| 117 |
+ 0xE8BD4004, |
|
| 118 |
+ 0xE3A0C0D3, |
|
| 119 |
+ 0xE129F00C, |
|
| 120 |
+ 0xE8BD0800, |
|
| 121 |
+ 0xE169F00B, |
|
| 122 |
+ 0xE8BD5800, |
|
| 123 |
+ 0xE1B0F00E, |
|
| 124 |
+ 0x0000009C, |
|
| 125 |
+ 0x0000009C, |
|
| 126 |
+ 0x0000009C, |
|
| 127 |
+ 0x0000009C, |
|
| 128 |
+ 0x000001F8, |
|
| 129 |
+ 0x000001F0, |
|
| 130 |
+ 0x000000AC, |
|
| 131 |
+ 0x000000A0, |
|
| 132 |
+ 0x000000FC, |
|
| 133 |
+ 0x00000168, |
|
| 134 |
+ 0xE12FFF1E, |
|
| 135 |
+ 0xE1A03000, |
|
| 136 |
+ 0xE1A00001, |
|
| 137 |
+ 0xE1A01003, |
|
| 138 |
+ 0xE2113102, |
|
| 139 |
+ 0x42611000, |
|
| 140 |
+ 0xE033C040, |
|
| 141 |
+ 0x22600000, |
|
| 142 |
+ 0xE1B02001, |
|
| 143 |
+ 0xE15200A0, |
|
| 144 |
+ 0x91A02082, |
|
| 145 |
+ 0x3AFFFFFC, |
|
| 146 |
+ 0xE1500002, |
|
| 147 |
+ 0xE0A33003, |
|
| 148 |
+ 0x20400002, |
|
| 149 |
+ 0xE1320001, |
|
| 150 |
+ 0x11A020A2, |
|
| 151 |
+ 0x1AFFFFF9, |
|
| 152 |
+ 0xE1A01000, |
|
| 153 |
+ 0xE1A00003, |
|
| 154 |
+ 0xE1B0C08C, |
|
| 155 |
+ 0x22600000, |
|
| 156 |
+ 0x42611000, |
|
| 157 |
+ 0xE12FFF1E, |
|
| 158 |
+ 0xE92D0010, |
|
| 159 |
+ 0xE1A0C000, |
|
| 160 |
+ 0xE3A01001, |
|
| 161 |
+ 0xE1500001, |
|
| 162 |
+ 0x81A000A0, |
|
| 163 |
+ 0x81A01081, |
|
| 164 |
+ 0x8AFFFFFB, |
|
| 165 |
+ 0xE1A0000C, |
|
| 166 |
+ 0xE1A04001, |
|
| 167 |
+ 0xE3A03000, |
|
| 168 |
+ 0xE1A02001, |
|
| 169 |
+ 0xE15200A0, |
|
| 170 |
+ 0x91A02082, |
|
| 171 |
+ 0x3AFFFFFC, |
|
| 172 |
+ 0xE1500002, |
|
| 173 |
+ 0xE0A33003, |
|
| 174 |
+ 0x20400002, |
|
| 175 |
+ 0xE1320001, |
|
| 176 |
+ 0x11A020A2, |
|
| 177 |
+ 0x1AFFFFF9, |
|
| 178 |
+ 0xE0811003, |
|
| 179 |
+ 0xE1B010A1, |
|
| 180 |
+ 0xE1510004, |
|
| 181 |
+ 0x3AFFFFEE, |
|
| 182 |
+ 0xE1A00004, |
|
| 183 |
+ 0xE8BD0010, |
|
| 184 |
+ 0xE12FFF1E, |
|
| 185 |
+ 0xE0010090, |
|
| 186 |
+ 0xE1A01741, |
|
| 187 |
+ 0xE2611000, |
|
| 188 |
+ 0xE3A030A9, |
|
| 189 |
+ 0xE0030391, |
|
| 190 |
+ 0xE1A03743, |
|
| 191 |
+ 0xE2833E39, |
|
| 192 |
+ 0xE0030391, |
|
| 193 |
+ 0xE1A03743, |
|
| 194 |
+ 0xE2833C09, |
|
| 195 |
+ 0xE283301C, |
|
| 196 |
+ 0xE0030391, |
|
| 197 |
+ 0xE1A03743, |
|
| 198 |
+ 0xE2833C0F, |
|
| 199 |
+ 0xE28330B6, |
|
| 200 |
+ 0xE0030391, |
|
| 201 |
+ 0xE1A03743, |
|
| 202 |
+ 0xE2833C16, |
|
| 203 |
+ 0xE28330AA, |
|
| 204 |
+ 0xE0030391, |
|
| 205 |
+ 0xE1A03743, |
|
| 206 |
+ 0xE2833A02, |
|
| 207 |
+ 0xE2833081, |
|
| 208 |
+ 0xE0030391, |
|
| 209 |
+ 0xE1A03743, |
|
| 210 |
+ 0xE2833C36, |
|
| 211 |
+ 0xE2833051, |
|
| 212 |
+ 0xE0030391, |
|
| 213 |
+ 0xE1A03743, |
|
| 214 |
+ 0xE2833CA2, |
|
| 215 |
+ 0xE28330F9, |
|
| 216 |
+ 0xE0000093, |
|
| 217 |
+ 0xE1A00840, |
|
| 218 |
+ 0xE12FFF1E, |
|
| 219 |
+ 0xE3A00001, |
|
| 220 |
+ 0xE3A01001, |
|
| 221 |
+ 0xE92D4010, |
|
| 222 |
+ 0xE3A03000, |
|
| 223 |
+ 0xE3A04001, |
|
| 224 |
+ 0xE3500000, |
|
| 225 |
+ 0x1B000004, |
|
| 226 |
+ 0xE5CC3301, |
|
| 227 |
+ 0xEB000002, |
|
| 228 |
+ 0x0AFFFFFC, |
|
| 229 |
+ 0xE8BD4010, |
|
| 230 |
+ 0xE12FFF1E, |
|
| 231 |
+ 0xE3A0C301, |
|
| 232 |
+ 0xE5CC3208, |
|
| 233 |
+ 0xE15C20B8, |
|
| 234 |
+ 0xE0110002, |
|
| 235 |
+ 0x10222000, |
|
| 236 |
+ 0x114C20B8, |
|
| 237 |
+ 0xE5CC4208, |
|
| 238 |
+ 0xE12FFF1E, |
|
| 239 |
+ 0xE92D500F, |
|
| 240 |
+ 0xE3A00301, |
|
| 241 |
+ 0xE1A0E00F, |
|
| 242 |
+ 0xE510F004, |
|
| 243 |
+ 0xE8BD500F, |
|
| 244 |
+ 0xE25EF004, |
|
| 245 |
+ 0xE59FD044, |
|
| 246 |
+ 0xE92D5000, |
|
| 247 |
+ 0xE14FC000, |
|
| 248 |
+ 0xE10FE000, |
|
| 249 |
+ 0xE92D5000, |
|
| 250 |
+ 0xE3A0C302, |
|
| 251 |
+ 0xE5DCE09C, |
|
| 252 |
+ 0xE35E00A5, |
|
| 253 |
+ 0x1A000004, |
|
| 254 |
+ 0x05DCE0B4, |
|
| 255 |
+ 0x021EE080, |
|
| 256 |
+ 0xE28FE004, |
|
| 257 |
+ 0x159FF018, |
|
| 258 |
+ 0x059FF018, |
|
| 259 |
+ 0xE59FD018, |
|
| 260 |
+ 0xE8BD5000, |
|
| 261 |
+ 0xE169F00C, |
|
| 262 |
+ 0xE8BD5000, |
|
| 263 |
+ 0xE25EF004, |
|
| 264 |
+ 0x03007FF0, |
|
| 265 |
+ 0x09FE2000, |
|
| 266 |
+ 0x09FFC000, |
|
| 267 |
+ 0x03007FE0 |
|
| 338 | 268 |
}; |
| 339 | 269 |
|
| 340 |
-/*variable_desc saveGameStruct[] = {
|
|
| 341 |
- { &DISPCNT , sizeof(u16) },
|
|
| 342 |
- { &DISPSTAT , sizeof(u16) },
|
|
| 343 |
- { &VCOUNT , sizeof(u16) },
|
|
| 344 |
- { &BG0CNT , sizeof(u16) },
|
|
| 345 |
- { &BG1CNT , sizeof(u16) },
|
|
| 346 |
- { &BG2CNT , sizeof(u16) },
|
|
| 347 |
- { &BG3CNT , sizeof(u16) },
|
|
| 348 |
- { &BG0HOFS , sizeof(u16) },
|
|
| 349 |
- { &BG0VOFS , sizeof(u16) },
|
|
| 350 |
- { &BG1HOFS , sizeof(u16) },
|
|
| 351 |
- { &BG1VOFS , sizeof(u16) },
|
|
| 352 |
- { &BG2HOFS , sizeof(u16) },
|
|
| 353 |
- { &BG2VOFS , sizeof(u16) },
|
|
| 354 |
- { &BG3HOFS , sizeof(u16) },
|
|
| 355 |
- { &BG3VOFS , sizeof(u16) },
|
|
| 356 |
- { &BG2PA , sizeof(u16) },
|
|
| 357 |
- { &BG2PB , sizeof(u16) },
|
|
| 358 |
- { &BG2PC , sizeof(u16) },
|
|
| 359 |
- { &BG2PD , sizeof(u16) },
|
|
| 360 |
- { &BG2X_L , sizeof(u16) },
|
|
| 361 |
- { &BG2X_H , sizeof(u16) },
|
|
| 362 |
- { &BG2Y_L , sizeof(u16) },
|
|
| 363 |
- { &BG2Y_H , sizeof(u16) },
|
|
| 364 |
- { &BG3PA , sizeof(u16) },
|
|
| 365 |
- { &BG3PB , sizeof(u16) },
|
|
| 366 |
- { &BG3PC , sizeof(u16) },
|
|
| 367 |
- { &BG3PD , sizeof(u16) },
|
|
| 368 |
- { &BG3X_L , sizeof(u16) },
|
|
| 369 |
- { &BG3X_H , sizeof(u16) },
|
|
| 370 |
- { &BG3Y_L , sizeof(u16) },
|
|
| 371 |
- { &BG3Y_H , sizeof(u16) },
|
|
| 372 |
- { &WIN0H , sizeof(u16) },
|
|
| 373 |
- { &WIN1H , sizeof(u16) },
|
|
| 374 |
- { &WIN0V , sizeof(u16) },
|
|
| 375 |
- { &WIN1V , sizeof(u16) },
|
|
| 376 |
- { &WININ , sizeof(u16) },
|
|
| 377 |
- { &WINOUT , sizeof(u16) },
|
|
| 378 |
- { &MOSAIC , sizeof(u16) },
|
|
| 379 |
- { &BLDMOD , sizeof(u16) },
|
|
| 380 |
- { &COLEV , sizeof(u16) },
|
|
| 381 |
- { &COLY , sizeof(u16) },
|
|
| 382 |
- { &DM0SAD_L , sizeof(u16) },
|
|
| 383 |
- { &DM0SAD_H , sizeof(u16) },
|
|
| 384 |
- { &DM0DAD_L , sizeof(u16) },
|
|
| 385 |
- { &DM0DAD_H , sizeof(u16) },
|
|
| 386 |
- { &DM0CNT_L , sizeof(u16) },
|
|
| 387 |
- { &DM0CNT_H , sizeof(u16) },
|
|
| 388 |
- { &DM1SAD_L , sizeof(u16) },
|
|
| 389 |
- { &DM1SAD_H , sizeof(u16) },
|
|
| 390 |
- { &DM1DAD_L , sizeof(u16) },
|
|
| 391 |
- { &DM1DAD_H , sizeof(u16) },
|
|
| 392 |
- { &DM1CNT_L , sizeof(u16) },
|
|
| 393 |
- { &DM1CNT_H , sizeof(u16) },
|
|
| 394 |
- { &DM2SAD_L , sizeof(u16) },
|
|
| 395 |
- { &DM2SAD_H , sizeof(u16) },
|
|
| 396 |
- { &DM2DAD_L , sizeof(u16) },
|
|
| 397 |
- { &DM2DAD_H , sizeof(u16) },
|
|
| 398 |
- { &DM2CNT_L , sizeof(u16) },
|
|
| 399 |
- { &DM2CNT_H , sizeof(u16) },
|
|
| 400 |
- { &DM3SAD_L , sizeof(u16) },
|
|
| 401 |
- { &DM3SAD_H , sizeof(u16) },
|
|
| 402 |
- { &DM3DAD_L , sizeof(u16) },
|
|
| 403 |
- { &DM3DAD_H , sizeof(u16) },
|
|
| 404 |
- { &DM3CNT_L , sizeof(u16) },
|
|
| 405 |
- { &DM3CNT_H , sizeof(u16) },
|
|
| 406 |
- { &TM0D , sizeof(u16) },
|
|
| 407 |
- { &TM0CNT , sizeof(u16) },
|
|
| 408 |
- { &TM1D , sizeof(u16) },
|
|
| 409 |
- { &TM1CNT , sizeof(u16) },
|
|
| 410 |
- { &TM2D , sizeof(u16) },
|
|
| 411 |
- { &TM2CNT , sizeof(u16) },
|
|
| 412 |
- { &TM3D , sizeof(u16) },
|
|
| 413 |
- { &TM3CNT , sizeof(u16) },
|
|
| 414 |
- { &P1 , sizeof(u16) },
|
|
| 415 |
- { &IE , sizeof(u16) },
|
|
| 416 |
- { &IF , sizeof(u16) },
|
|
| 417 |
- { &IME , sizeof(u16) },
|
|
| 418 |
- { &holdState, sizeof(bool) },
|
|
| 419 |
- { &holdType, sizeof(int) },
|
|
| 420 |
- { &lcdTicks, sizeof(int) },
|
|
| 421 |
- { &timer0On , sizeof(bool) },
|
|
| 422 |
- { &timer0Ticks , sizeof(int) },
|
|
| 423 |
- { &timer0Reload , sizeof(int) },
|
|
| 424 |
- { &timer0ClockReload , sizeof(int) },
|
|
| 425 |
- { &timer1On , sizeof(bool) },
|
|
| 426 |
- { &timer1Ticks , sizeof(int) },
|
|
| 427 |
- { &timer1Reload , sizeof(int) },
|
|
| 428 |
- { &timer1ClockReload , sizeof(int) },
|
|
| 429 |
- { &timer2On , sizeof(bool) },
|
|
| 430 |
- { &timer2Ticks , sizeof(int) },
|
|
| 431 |
- { &timer2Reload , sizeof(int) },
|
|
| 432 |
- { &timer2ClockReload , sizeof(int) },
|
|
| 433 |
- { &timer3On , sizeof(bool) },
|
|
| 434 |
- { &timer3Ticks , sizeof(int) },
|
|
| 435 |
- { &timer3Reload , sizeof(int) },
|
|
| 436 |
- { &timer3ClockReload , sizeof(int) },
|
|
| 437 |
- { &dma0Source , sizeof(u32) },
|
|
| 438 |
- { &dma0Dest , sizeof(u32) },
|
|
| 439 |
- { &dma1Source , sizeof(u32) },
|
|
| 440 |
- { &dma1Dest , sizeof(u32) },
|
|
| 441 |
- { &dma2Source , sizeof(u32) },
|
|
| 442 |
- { &dma2Dest , sizeof(u32) },
|
|
| 443 |
- { &dma3Source , sizeof(u32) },
|
|
| 444 |
- { &dma3Dest , sizeof(u32) },
|
|
| 445 |
- { &fxOn, sizeof(bool) },
|
|
| 446 |
- { &windowOn, sizeof(bool) },
|
|
| 447 |
- { &N_FLAG , sizeof(bool) },
|
|
| 448 |
- { &C_FLAG , sizeof(bool) },
|
|
| 449 |
- { &Z_FLAG , sizeof(bool) },
|
|
| 450 |
- { &V_FLAG , sizeof(bool) },
|
|
| 451 |
- { &armState , sizeof(bool) },
|
|
| 452 |
- { &armIrqEnable , sizeof(bool) },
|
|
| 453 |
- { &armNextPC , sizeof(u32) },
|
|
| 454 |
- { &armMode , sizeof(int) },
|
|
| 455 |
- { &saveType , sizeof(int) },
|
|
| 456 |
- { NULL, 0 }
|
|
| 457 |
-};*/ |
|
| 458 |
- |
|
| 459 | 270 |
static int romSize = 0x2000000; |
| 460 | 271 |
|
| 461 |
-#ifdef PROFILING |
|
| 462 |
-void cpuProfil(profile_segment *seg) |
|
| 463 |
-{
|
|
| 464 |
- profilSegment = seg; |
|
| 465 |
-} |
|
| 466 |
- |
|
| 467 |
-void cpuEnableProfiling(int hz) |
|
| 468 |
-{
|
|
| 469 |
- if(hz == 0) |
|
| 470 |
- hz = 100; |
|
| 471 |
- profilingTicks = profilingTicksReload = 16777216 / hz; |
|
| 472 |
- profSetHertz(hz); |
|
| 473 |
-} |
|
| 474 |
-#endif |
|
| 475 |
- |
|
| 476 |
- |
|
| 477 |
-inline int CPUUpdateTicks() |
|
| 478 |
-{
|
|
| 479 |
- int cpuLoopTicks = lcdTicks; |
|
| 480 |
- |
|
| 481 |
- if(soundTicks < cpuLoopTicks) |
|
| 482 |
- cpuLoopTicks = soundTicks; |
|
| 483 |
- |
|
| 484 |
- if(timer0On && (timer0Ticks < cpuLoopTicks)) {
|
|
| 485 |
- cpuLoopTicks = timer0Ticks; |
|
| 486 |
- } |
|
| 487 |
- if(timer1On && !(TM1CNT & 4) && (timer1Ticks < cpuLoopTicks)) {
|
|
| 488 |
- cpuLoopTicks = timer1Ticks; |
|
| 489 |
- } |
|
| 490 |
- if(timer2On && !(TM2CNT & 4) && (timer2Ticks < cpuLoopTicks)) {
|
|
| 491 |
- cpuLoopTicks = timer2Ticks; |
|
| 492 |
- } |
|
| 493 |
- if(timer3On && !(TM3CNT & 4) && (timer3Ticks < cpuLoopTicks)) {
|
|
| 494 |
- cpuLoopTicks = timer3Ticks; |
|
| 495 |
- } |
|
| 496 |
-#ifdef PROFILING |
|
| 497 |
- if(profilingTicksReload != 0) {
|
|
| 498 |
- if(profilingTicks < cpuLoopTicks) {
|
|
| 499 |
- cpuLoopTicks = profilingTicks; |
|
| 500 |
- } |
|
| 501 |
- } |
|
| 502 |
-#endif |
|
| 503 |
- |
|
| 504 |
- if (SWITicks) {
|
|
| 505 |
- if (SWITicks < cpuLoopTicks) |
|
| 506 |
- cpuLoopTicks = SWITicks; |
|
| 507 |
- } |
|
| 508 |
- |
|
| 509 |
- if (IRQTicks) {
|
|
| 510 |
- if (IRQTicks < cpuLoopTicks) |
|
| 511 |
- cpuLoopTicks = IRQTicks; |
|
| 512 |
- } |
|
| 513 |
- |
|
| 514 |
- return cpuLoopTicks; |
|
| 515 |
-} |
|
| 516 |
- |
|
| 517 |
-/*void CPUUpdateWindow0() |
|
| 518 |
-{
|
|
| 519 |
- int x00 = WIN0H>>8; |
|
| 520 |
- int x01 = WIN0H & 255; |
|
| 521 |
- |
|
| 522 |
- if(x00 <= x01) {
|
|
| 523 |
- for(int i = 0; i < 240; i++) {
|
|
| 524 |
- gfxInWin0[i] = (i >= x00 && i < x01); |
|
| 525 |
- } |
|
| 526 |
- } else {
|
|
| 527 |
- for(int i = 0; i < 240; i++) {
|
|
| 528 |
- gfxInWin0[i] = (i >= x00 || i < x01); |
|
| 529 |
- } |
|
| 530 |
- } |
|
| 531 |
-}*/ |
|
| 532 |
- |
|
| 533 |
-/*void CPUUpdateWindow1() |
|
| 534 |
-{
|
|
| 535 |
- int x00 = WIN1H>>8; |
|
| 536 |
- int x01 = WIN1H & 255; |
|
| 537 |
- |
|
| 538 |
- if(x00 <= x01) {
|
|
| 539 |
- for(int i = 0; i < 240; i++) {
|
|
| 540 |
- gfxInWin1[i] = (i >= x00 && i < x01); |
|
| 541 |
- } |
|
| 542 |
- } else {
|
|
| 543 |
- for(int i = 0; i < 240; i++) {
|
|
| 544 |
- gfxInWin1[i] = (i >= x00 || i < x01); |
|
| 545 |
- } |
|
| 546 |
- } |
|
| 547 |
-}*/ |
|
| 548 |
- |
|
| 549 |
-/*extern uint32_t line0[240]; |
|
| 550 |
-extern uint32_t line1[240]; |
|
| 551 |
-extern uint32_t line2[240]; |
|
| 552 |
-extern uint32_t line3[240]; |
|
| 553 |
- |
|
| 554 |
-#define CLEAR_ARRAY(a) \ |
|
| 555 |
- {\
|
|
| 556 |
- u32 *array = (a);\ |
|
| 557 |
- for(int i = 0; i < 240; i++) {\
|
|
| 558 |
- *array++ = 0x80000000;\ |
|
| 559 |
- }\ |
|
| 560 |
- }\*/ |
|
| 561 |
- |
|
| 562 |
-/*void CPUUpdateRenderBuffers(bool force) |
|
| 563 |
-{
|
|
| 564 |
- if(!(layerEnable & 0x0100) || force) {
|
|
| 565 |
- CLEAR_ARRAY(line0); |
|
| 566 |
- } |
|
| 567 |
- if(!(layerEnable & 0x0200) || force) {
|
|
| 568 |
- CLEAR_ARRAY(line1); |
|
| 569 |
- } |
|
| 570 |
- if(!(layerEnable & 0x0400) || force) {
|
|
| 571 |
- CLEAR_ARRAY(line2); |
|
| 572 |
- } |
|
| 573 |
- if(!(layerEnable & 0x0800) || force) {
|
|
| 574 |
- CLEAR_ARRAY(line3); |
|
| 575 |
- } |
|
| 576 |
-}*/ |
|
| 577 |
- |
|
| 578 |
-/*static bool CPUWriteState(gzFile gzFile) |
|
| 579 |
-{
|
|
| 580 |
- utilWriteInt(gzFile, SAVE_GAME_VERSION); |
|
| 581 |
- |
|
| 582 |
- utilGzWrite(gzFile, &rom[0xa0], 16); |
|
| 583 |
- |
|
| 584 |
- utilWriteInt(gzFile, useBios); |
|
| 585 |
- |
|
| 586 |
- utilGzWrite(gzFile, ®[0], sizeof(reg)); |
|
| 587 |
- |
|
| 588 |
- utilWriteData(gzFile, saveGameStruct); |
|
| 589 |
- |
|
| 590 |
- // new to version 0.7.1 |
|
| 591 |
- utilWriteInt(gzFile, stopState); |
|
| 592 |
- // new to version 0.8 |
|
| 593 |
- utilWriteInt(gzFile, IRQTicks); |
|
| 594 |
- |
|
| 595 |
- utilGzWrite(gzFile, internalRAM, 0x8000); |
|
| 596 |
- utilGzWrite(gzFile, paletteRAM, 0x400); |
|
| 597 |
- utilGzWrite(gzFile, workRAM, 0x40000); |
|
| 598 |
- utilGzWrite(gzFile, vram, 0x20000); |
|
| 599 |
- utilGzWrite(gzFile, oam, 0x400); |
|
| 600 |
- utilGzWrite(gzFile, pix, 4*241*162); |
|
| 601 |
- utilGzWrite(gzFile, ioMem, 0x400); |
|
| 602 |
- |
|
| 603 |
- eepromSaveGame(gzFile); |
|
| 604 |
- flashSaveGame(gzFile); |
|
| 605 |
- soundSaveGame(gzFile); |
|
| 606 |
- |
|
| 607 |
- cheatsSaveGame(gzFile); |
|
| 608 |
- |
|
| 609 |
- // version 1.5 |
|
| 610 |
- rtcSaveGame(gzFile); |
|
| 611 |
- |
|
| 612 |
- return true; |
|
| 613 |
-} |
|
| 614 |
- |
|
| 615 |
-bool CPUWriteState(const char *file) |
|
| 616 |
-{
|
|
| 617 |
- gzFile gzFile = utilGzOpen(file, "wb"); |
|
| 618 |
- |
|
| 619 |
- if(gzFile == NULL) {
|
|
| 620 |
- systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), file);
|
|
| 621 |
- return false; |
|
| 622 |
- } |
|
| 623 |
- |
|
| 624 |
- bool res = CPUWriteState(gzFile); |
|
| 625 |
- |
|
| 626 |
- utilGzClose(gzFile); |
|
| 627 |
- |
|
| 628 |
- return res; |
|
| 629 |
-} |
|
| 630 |
- |
|
| 631 |
-bool CPUWriteMemState(char *memory, int available) |
|
| 632 |
-{
|
|
| 633 |
- gzFile gzFile = utilMemGzOpen(memory, available, "w"); |
|
| 634 |
- |
|
| 635 |
- if(gzFile == NULL) {
|
|
| 636 |
- return false; |
|
| 637 |
- } |
|
| 638 |
- |
|
| 639 |
- bool res = CPUWriteState(gzFile); |
|
| 640 |
- |
|
| 641 |
- long pos = utilGzMemTell(gzFile)+8; |
|
| 642 |
- |
|
| 643 |
- if(pos >= (available)) |
|
| 644 |
- res = false; |
|
| 645 |
- |
|
| 646 |
- utilGzClose(gzFile); |
|
| 647 |
- |
|
| 648 |
- return res; |
|
| 649 |
-} |
|
| 650 |
- |
|
| 651 |
-static bool CPUReadState(gzFile gzFile) |
|
| 652 |
-{
|
|
| 653 |
- int version = utilReadInt(gzFile); |
|
| 654 |
- |
|
| 655 |
- if(version > SAVE_GAME_VERSION || version < SAVE_GAME_VERSION_1) {
|
|
| 656 |
- systemMessage(MSG_UNSUPPORTED_VBA_SGM, |
|
| 657 |
- N_("Unsupported VisualBoyAdvance save game version %d"),
|
|
| 658 |
- version); |
|
| 659 |
- return false; |
|
| 660 |
- } |
|
| 661 |
- |
|
| 662 |
- u8 romname[17]; |
|
| 663 |
- |
|
| 664 |
- utilGzRead(gzFile, romname, 16); |
|
| 665 |
- |
|
| 666 |
- if(memcmp(&rom[0xa0], romname, 16) != 0) {
|
|
| 667 |
- romname[16]=0; |
|
| 668 |
- for(int i = 0; i < 16; i++) |
|
| 669 |
- if(romname[i] < 32) |
|
| 670 |
- romname[i] = 32; |
|
| 671 |
- systemMessage(MSG_CANNOT_LOAD_SGM, N_("Cannot load save game for %s"), romname);
|
|
| 672 |
- return false; |
|
| 673 |
- } |
|
| 674 |
- |
|
| 675 |
- bool ub = utilReadInt(gzFile) ? true : false; |
|
| 676 |
- |
|
| 677 |
- if(ub != useBios) {
|
|
| 678 |
- if(useBios) |
|
| 679 |
- systemMessage(MSG_SAVE_GAME_NOT_USING_BIOS, |
|
| 680 |
- N_("Save game is not using the BIOS files"));
|
|
| 681 |
- else |
|
| 682 |
- systemMessage(MSG_SAVE_GAME_USING_BIOS, |
|
| 683 |
- N_("Save game is using the BIOS file"));
|
|
| 684 |
- return false; |
|
| 685 |
- } |
|
| 686 |
- |
|
| 687 |
- utilGzRead(gzFile, ®[0], sizeof(reg)); |
|
| 688 |
- |
|
| 689 |
- utilReadData(gzFile, saveGameStruct); |
|
| 690 |
- |
|
| 691 |
- if(version < SAVE_GAME_VERSION_3) |
|
| 692 |
- stopState = false; |
|
| 693 |
- else |
|
| 694 |
- stopState = utilReadInt(gzFile) ? true : false; |
|
| 695 |
- |
|
| 696 |
- if(version < SAVE_GAME_VERSION_4) |
|
| 697 |
- {
|
|
| 698 |
- IRQTicks = 0; |
|
| 699 |
- intState = false; |
|
| 700 |
- } |
|
| 701 |
- else |
|
| 702 |
- {
|
|
| 703 |
- IRQTicks = utilReadInt(gzFile); |
|
| 704 |
- if (IRQTicks>0) |
|
| 705 |
- intState = true; |
|
| 706 |
- else |
|
| 707 |
- {
|
|
| 708 |
- intState = false; |
|
| 709 |
- IRQTicks = 0; |
|
| 710 |
- } |
|
| 711 |
- } |
|
| 712 |
- |
|
| 713 |
- utilGzRead(gzFile, internalRAM, 0x8000); |
|
| 714 |
- utilGzRead(gzFile, paletteRAM, 0x400); |
|
| 715 |
- utilGzRead(gzFile, workRAM, 0x40000); |
|
| 716 |
- utilGzRead(gzFile, vram, 0x20000); |
|
| 717 |
- utilGzRead(gzFile, oam, 0x400); |
|
| 718 |
- if(version < SAVE_GAME_VERSION_6) |
|
| 719 |
- utilGzRead(gzFile, pix, 4*240*160); |
|
| 720 |
- else |
|
| 721 |
- utilGzRead(gzFile, pix, 4*241*162); |
|
| 722 |
- utilGzRead(gzFile, ioMem, 0x400); |
|
| 723 |
- |
|
| 724 |
- if(skipSaveGameBattery) {
|
|
| 725 |
- // skip eeprom data |
|
| 726 |
- eepromReadGameSkip(gzFile, version); |
|
| 727 |
- // skip flash data |
|
| 728 |
- flashReadGameSkip(gzFile, version); |
|
| 729 |
- } else {
|
|
| 730 |
- eepromReadGame(gzFile, version); |
|
| 731 |
- flashReadGame(gzFile, version); |
|
| 732 |
- } |
|
| 733 |
- soundReadGame(gzFile, version); |
|
| 734 |
- |
|
| 735 |
- if(version > SAVE_GAME_VERSION_1) {
|
|
| 736 |
- if(skipSaveGameCheats) {
|
|
| 737 |
- // skip cheats list data |
|
| 738 |
- cheatsReadGameSkip(gzFile, version); |
|
| 739 |
- } else {
|
|
| 740 |
- cheatsReadGame(gzFile, version); |
|
| 741 |
- } |
|
| 742 |
- } |
|
| 743 |
- if(version > SAVE_GAME_VERSION_6) {
|
|
| 744 |
- rtcReadGame(gzFile); |
|
| 745 |
- } |
|
| 746 |
- |
|
| 747 |
- if(version <= SAVE_GAME_VERSION_7) {
|
|
| 748 |
- u32 temp; |
|
| 749 |
-#define SWAP(a,b,c) \ |
|
| 750 |
- temp = (a);\ |
|
| 751 |
- (a) = (b)<<16|(c);\ |
|
| 752 |
- (b) = (temp) >> 16;\ |
|
| 753 |
- (c) = (temp) & 0xFFFF; |
|
| 754 |
- |
|
| 755 |
- SWAP(dma0Source, DM0SAD_H, DM0SAD_L); |
|
| 756 |
- SWAP(dma0Dest, DM0DAD_H, DM0DAD_L); |
|
| 757 |
- SWAP(dma1Source, DM1SAD_H, DM1SAD_L); |
|
| 758 |
- SWAP(dma1Dest, DM1DAD_H, DM1DAD_L); |
|
| 759 |
- SWAP(dma2Source, DM2SAD_H, DM2SAD_L); |
|
| 760 |
- SWAP(dma2Dest, DM2DAD_H, DM2DAD_L); |
|
| 761 |
- SWAP(dma3Source, DM3SAD_H, DM3SAD_L); |
|
| 762 |
- SWAP(dma3Dest, DM3DAD_H, DM3DAD_L); |
|
| 763 |
- } |
|
| 764 |
- |
|
| 765 |
- if(version <= SAVE_GAME_VERSION_8) {
|
|
| 766 |
- timer0ClockReload = TIMER_TICKS[TM0CNT & 3]; |
|
| 767 |
- timer1ClockReload = TIMER_TICKS[TM1CNT & 3]; |
|
| 768 |
- timer2ClockReload = TIMER_TICKS[TM2CNT & 3]; |
|
| 769 |
- timer3ClockReload = TIMER_TICKS[TM3CNT & 3]; |
|
| 770 |
- |
|
| 771 |
- timer0Ticks = ((0x10000 - TM0D) << timer0ClockReload) - timer0Ticks; |
|
| 772 |
- timer1Ticks = ((0x10000 - TM1D) << timer1ClockReload) - timer1Ticks; |
|
| 773 |
- timer2Ticks = ((0x10000 - TM2D) << timer2ClockReload) - timer2Ticks; |
|
| 774 |
- timer3Ticks = ((0x10000 - TM3D) << timer3ClockReload) - timer3Ticks; |
|
| 775 |
- interp_rate(); |
|
| 776 |
- } |
|
| 777 |
- |
|
| 778 |
- // set pointers! |
|
| 779 |
- layerEnable = layerSettings & DISPCNT; |
|
| 780 |
- |
|
| 781 |
- CPUUpdateRender(); |
|
| 782 |
- //CPUUpdateRenderBuffers(true); |
|
| 783 |
- //CPUUpdateWindow0(); |
|
| 784 |
- //CPUUpdateWindow1(); |
|
| 785 |
- gbaSaveType = 0; |
|
| 786 |
- switch(saveType) {
|
|
| 787 |
- case 0: |
|
| 788 |
- cpuSaveGameFunc = flashSaveDecide; |
|
| 789 |
- break; |
|
| 790 |
- case 1: |
|
| 791 |
- cpuSaveGameFunc = sramWrite; |
|
| 792 |
- gbaSaveType = 1; |
|
| 793 |
- break; |
|
| 794 |
- case 2: |
|
| 795 |
- cpuSaveGameFunc = flashWrite; |
|
| 796 |
- gbaSaveType = 2; |
|
| 797 |
- break; |
|
| 798 |
- case 3: |
|
| 799 |
- break; |
|
| 800 |
- case 5: |
|
| 801 |
- gbaSaveType = 5; |
|
| 802 |
- break; |
|
| 803 |
- default: |
|
| 804 |
- systemMessage(MSG_UNSUPPORTED_SAVE_TYPE, |
|
| 805 |
- N_("Unsupported save type %d"), saveType);
|
|
| 806 |
- break; |
|
| 807 |
- } |
|
| 808 |
- if(eepromInUse) |
|
| 809 |
- gbaSaveType = 3; |
|
| 810 |
- |
|
| 811 |
- systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 812 |
- if(armState) {
|
|
| 813 |
- ARM_PREFETCH; |
|
| 814 |
- } else {
|
|
| 815 |
- THUMB_PREFETCH; |
|
| 816 |
- } |
|
| 817 |
- |
|
| 818 |
- CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204)); |
|
| 819 |
- |
|
| 820 |
- return true; |
|
| 821 |
-} |
|
| 822 |
- |
|
| 823 |
-bool CPUReadMemState(char *memory, int available) |
|
| 824 |
-{
|
|
| 825 |
- gzFile gzFile = utilMemGzOpen(memory, available, "r"); |
|
| 826 |
- |
|
| 827 |
- bool res = CPUReadState(gzFile); |
|
| 828 |
- |
|
| 829 |
- utilGzClose(gzFile); |
|
| 830 |
- |
|
| 831 |
- return res; |
|
| 832 |
-} |
|
| 833 |
- |
|
| 834 |
-bool CPUReadState(const char * file) |
|
| 272 |
+static inline int CPUUpdateTicks() |
|
| 835 | 273 |
{
|
| 836 |
- gzFile gzFile = utilGzOpen(file, "rb"); |
|
| 837 |
- |
|
| 838 |
- if(gzFile == NULL) |
|
| 839 |
- return false; |
|
| 840 |
- |
|
| 841 |
- bool res = CPUReadState(gzFile); |
|
| 842 |
- |
|
| 843 |
- utilGzClose(gzFile); |
|
| 274 |
+ int cpuLoopTicks = lcdTicks; |
|
| 844 | 275 |
|
| 845 |
- return res; |
|
| 846 |
-} |
|
| 276 |
+ if (soundTicks < cpuLoopTicks) |
|
| 277 |
+ cpuLoopTicks = soundTicks; |
|
| 847 | 278 |
|
| 848 |
-bool CPUExportEepromFile(const char *fileName) |
|
| 849 |
-{
|
|
| 850 |
- if(eepromInUse) {
|
|
| 851 |
- FILE *file = fopen(fileName, "wb"); |
|
| 852 |
- |
|
| 853 |
- if(!file) {
|
|
| 854 |
- systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
|
|
| 855 |
- fileName); |
|
| 856 |
- return false; |
|
| 857 |
- } |
|
| 858 |
- |
|
| 859 |
- for(int i = 0; i < eepromSize;) {
|
|
| 860 |
- for(int j = 0; j < 8; j++) {
|
|
| 861 |
- if(fwrite(&eepromData[i+7-j], 1, 1, file) != 1) {
|
|
| 862 |
- fclose(file); |
|
| 863 |
- return false; |
|
| 864 |
- } |
|
| 865 |
- } |
|
| 866 |
- i += 8; |
|
| 867 |
- } |
|
| 868 |
- fclose(file); |
|
| 869 |
- } |
|
| 870 |
- return true; |
|
| 871 |
-} |
|
| 279 |
+ if (timer0On && timer0Ticks < cpuLoopTicks) |
|
| 280 |
+ cpuLoopTicks = timer0Ticks; |
|
| 281 |
+ if (timer1On && !(TM1CNT & 4) && timer1Ticks < cpuLoopTicks) |
|
| 282 |
+ cpuLoopTicks = timer1Ticks; |
|
| 283 |
+ if (timer2On && !(TM2CNT & 4) && timer2Ticks < cpuLoopTicks) |
|
| 284 |
+ cpuLoopTicks = timer2Ticks; |
|
| 285 |
+ if (timer3On && !(TM3CNT & 4) && timer3Ticks < cpuLoopTicks) |
|
| 286 |
+ cpuLoopTicks = timer3Ticks; |
|
| 872 | 287 |
|
| 873 |
-bool CPUWriteBatteryFile(const char *fileName) |
|
| 874 |
-{
|
|
| 875 |
- if(gbaSaveType == 0) {
|
|
| 876 |
- if(eepromInUse) |
|
| 877 |
- gbaSaveType = 3; |
|
| 878 |
- else switch(saveType) {
|
|
| 879 |
- case 1: |
|
| 880 |
- gbaSaveType = 1; |
|
| 881 |
- break; |
|
| 882 |
- case 2: |
|
| 883 |
- gbaSaveType = 2; |
|
| 884 |
- break; |
|
| 885 |
- } |
|
| 886 |
- } |
|
| 887 |
- |
|
| 888 |
- if((gbaSaveType) && (gbaSaveType!=5)) {
|
|
| 889 |
- FILE *file = fopen(fileName, "wb"); |
|
| 890 |
- |
|
| 891 |
- if(!file) {
|
|
| 892 |
- systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
|
|
| 893 |
- fileName); |
|
| 894 |
- return false; |
|
| 895 |
- } |
|
| 896 |
- |
|
| 897 |
- // only save if Flash/Sram in use or EEprom in use |
|
| 898 |
- if(gbaSaveType != 3) {
|
|
| 899 |
- if(gbaSaveType == 2) {
|
|
| 900 |
- if(fwrite(flashSaveMemory, 1, flashSize, file) != (size_t)flashSize) {
|
|
| 901 |
- fclose(file); |
|
| 902 |
- return false; |
|
| 903 |
- } |
|
| 904 |
- } else {
|
|
| 905 |
- if(fwrite(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
|
|
| 906 |
- fclose(file); |
|
| 907 |
- return false; |
|
| 908 |
- } |
|
| 909 |
- } |
|
| 910 |
- } else {
|
|
| 911 |
- if(fwrite(eepromData, 1, eepromSize, file) != (size_t)eepromSize) {
|
|
| 912 |
- fclose(file); |
|
| 913 |
- return false; |
|
| 914 |
- } |
|
| 915 |
- } |
|
| 916 |
- fclose(file); |
|
| 917 |
- } |
|
| 918 |
- return true; |
|
| 919 |
-} |
|
| 288 |
+ if (SWITicks && SWITicks < cpuLoopTicks) |
|
| 289 |
+ cpuLoopTicks = SWITicks; |
|
| 920 | 290 |
|
| 921 |
-bool CPUReadGSASnapshot(const char *fileName) |
|
| 922 |
-{
|
|
| 923 |
- int i; |
|
| 924 |
- FILE *file = fopen(fileName, "rb"); |
|
| 925 |
- |
|
| 926 |
- if(!file) {
|
|
| 927 |
- systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
|
|
| 928 |
- return false; |
|
| 929 |
- } |
|
| 930 |
- |
|
| 931 |
- // check file size to know what we should read |
|
| 932 |
- fseek(file, 0, SEEK_END); |
|
| 933 |
- |
|
| 934 |
- // long size = ftell(file); |
|
| 935 |
- fseek(file, 0x0, SEEK_SET); |
|
| 936 |
- fread(&i, 1, 4, file); |
|
| 937 |
- fseek(file, i, SEEK_CUR); // Skip SharkPortSave |
|
| 938 |
-// fseek(file, 4, SEEK_CUR); // skip some sort of flag |
|
| 939 |
- fread(&i, 1, 4, file); // name length |
|
| 940 |
- fseek(file, i, SEEK_CUR); // skip name |
|
| 941 |
- fread(&i, 1, 4, file); // desc length |
|
| 942 |
- fseek(file, i, SEEK_CUR); // skip desc |
|
| 943 |
- fread(&i, 1, 4, file); // notes length |
|
| 944 |
- fseek(file, i, SEEK_CUR); // skip notes |
|
| 945 |
- int saveSize; |
|
| 946 |
- fread(&saveSize, 1, 4, file); // read length |
|
| 947 |
- saveSize -= 0x1c; // remove header size |
|
| 948 |
- char buffer[17]; |
|
| 949 |
- char buffer2[17]; |
|
| 950 |
- fread(buffer, 1, 16, file); |
|
| 951 |
- buffer[16] = 0; |
|
| 952 |
- for(i = 0; i < 16; i++) |
|
| 953 |
- if(buffer[i] < 32) |
|
| 954 |
- buffer[i] = 32; |
|
| 955 |
- memcpy(buffer2, &rom[0xa0], 16); |
|
| 956 |
- buffer2[16] = 0; |
|
| 957 |
- for(i = 0; i < 16; i++) |
|
| 958 |
- if(buffer2[i] < 32) |
|
| 959 |
- buffer2[i] = 32; |
|
| 960 |
- if(memcmp(buffer, buffer2, 16)) {
|
|
| 961 |
- systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR, |
|
| 962 |
- N_("Cannot import snapshot for %s. Current game is %s"),
|
|
| 963 |
- buffer, |
|
| 964 |
- buffer2); |
|
| 965 |
- fclose(file); |
|
| 966 |
- return false; |
|
| 967 |
- } |
|
| 968 |
- fseek(file, 12, SEEK_CUR); // skip some flags |
|
| 969 |
- if(saveSize >= 65536) {
|
|
| 970 |
- if(fread(flashSaveMemory, 1, saveSize, file) != (size_t)saveSize) {
|
|
| 971 |
- fclose(file); |
|
| 972 |
- return false; |
|
| 973 |
- } |
|
| 974 |
- } else {
|
|
| 975 |
- systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE, |
|
| 976 |
- N_("Unsupported snapshot file %s"),
|
|
| 977 |
- fileName); |
|
| 978 |
- fclose(file); |
|
| 979 |
- return false; |
|
| 980 |
- } |
|
| 981 |
- fclose(file); |
|
| 982 |
- CPUReset(); |
|
| 983 |
- return true; |
|
| 984 |
-} |
|
| 291 |
+ if (IRQTicks && IRQTicks < cpuLoopTicks) |
|
| 292 |
+ cpuLoopTicks = IRQTicks; |
|
| 985 | 293 |
|
| 986 |
-bool CPUReadGSASPSnapshot(const char *fileName) |
|
| 987 |
-{
|
|
| 988 |
- const char gsvfooter[] = "xV4\x12"; |
|
| 989 |
- const size_t namepos=0x0c, namesz=12; |
|
| 990 |
- const size_t footerpos=0x42c, footersz=4; |
|
| 991 |
- |
|
| 992 |
- char footer[footersz+1], romname[namesz+1], savename[namesz+1];; |
|
| 993 |
- FILE *file = fopen(fileName, "rb"); |
|
| 994 |
- |
|
| 995 |
- if(!file) {
|
|
| 996 |
- systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
|
|
| 997 |
- return false; |
|
| 998 |
- } |
|
| 999 |
- |
|
| 1000 |
- // read save name |
|
| 1001 |
- fseek(file, namepos, SEEK_SET); |
|
| 1002 |
- fread(savename, 1, namesz, file); |
|
| 1003 |
- savename[namesz] = 0; |
|
| 1004 |
- |
|
| 1005 |
- memcpy(romname, &rom[0xa0], namesz); |
|
| 1006 |
- romname[namesz] = 0; |
|
| 1007 |
- |
|
| 1008 |
- if(memcmp(romname, savename, namesz)) {
|
|
| 1009 |
- systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR, |
|
| 1010 |
- N_("Cannot import snapshot for %s. Current game is %s"),
|
|
| 1011 |
- savename, |
|
| 1012 |
- romname); |
|
| 1013 |
- fclose(file); |
|
| 1014 |
- return false; |
|
| 1015 |
- } |
|
| 1016 |
- |
|
| 1017 |
- // read footer tag |
|
| 1018 |
- fseek(file, footerpos, SEEK_SET); |
|
| 1019 |
- fread(footer, 1, footersz, file); |
|
| 1020 |
- footer[footersz] = 0; |
|
| 1021 |
- |
|
| 1022 |
- if(memcmp(footer, gsvfooter, footersz)) {
|
|
| 1023 |
- systemMessage(0, |
|
| 1024 |
- N_("Unsupported snapshot file %s. Footer '%s' at %u should be '%s'"),
|
|
| 1025 |
- fileName, |
|
| 1026 |
- footer, |
|
| 1027 |
- footerpos, |
|
| 1028 |
- gsvfooter); |
|
| 1029 |
- fclose(file); |
|
| 1030 |
- return false; |
|
| 1031 |
- } |
|
| 1032 |
- |
|
| 1033 |
- // Read up to 128k save |
|
| 1034 |
- fread(flashSaveMemory, 1, FLASH_128K_SZ, file); |
|
| 1035 |
- |
|
| 1036 |
- fclose(file); |
|
| 1037 |
- CPUReset(); |
|
| 1038 |
- return true; |
|
| 294 |
+ return cpuLoopTicks; |
|
| 1039 | 295 |
} |
| 1040 | 296 |
|
| 1041 |
- |
|
| 1042 |
-bool CPUWriteGSASnapshot(const char *fileName, |
|
| 1043 |
- const char *title, |
|
| 1044 |
- const char *desc, |
|
| 1045 |
- const char *notes) |
|
| 297 |
+int CPULoadRom() |
|
| 1046 | 298 |
{
|
| 1047 |
- FILE *file = fopen(fileName, "wb"); |
|
| 1048 |
- |
|
| 1049 |
- if(!file) {
|
|
| 1050 |
- systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
|
|
| 1051 |
- return false; |
|
| 1052 |
- } |
|
| 1053 |
- |
|
| 1054 |
- u8 buffer[17]; |
|
| 1055 |
- |
|
| 1056 |
- utilPutDword(buffer, 0x0d); // SharkPortSave length |
|
| 1057 |
- fwrite(buffer, 1, 4, file); |
|
| 1058 |
- fwrite("SharkPortSave", 1, 0x0d, file);
|
|
| 1059 |
- utilPutDword(buffer, 0x000f0000); |
|
| 1060 |
- fwrite(buffer, 1, 4, file); // save type 0x000f0000 = GBA save |
|
| 1061 |
- utilPutDword(buffer, (u32)strlen(title)); |
|
| 1062 |
- fwrite(buffer, 1, 4, file); // title length |
|
| 1063 |
- fwrite(title, 1, strlen(title), file); |
|
| 1064 |
- utilPutDword(buffer, (u32)strlen(desc)); |
|
| 1065 |
- fwrite(buffer, 1, 4, file); // desc length |
|
| 1066 |
- fwrite(desc, 1, strlen(desc), file); |
|
| 1067 |
- utilPutDword(buffer, (u32)strlen(notes)); |
|
| 1068 |
- fwrite(buffer, 1, 4, file); // notes length |
|
| 1069 |
- fwrite(notes, 1, strlen(notes), file); |
|
| 1070 |
- int saveSize = 0x10000; |
|
| 1071 |
- if(gbaSaveType == 2) |
|
| 1072 |
- saveSize = flashSize; |
|
| 1073 |
- int totalSize = saveSize + 0x1c; |
|
| 1074 |
- |
|
| 1075 |
- utilPutDword(buffer, totalSize); // length of remainder of save - CRC |
|
| 1076 |
- fwrite(buffer, 1, 4, file); |
|
| 1077 |
- |
|
| 1078 |
- char *temp = new char[0x2001c]; |
|
| 1079 |
- memset(temp, 0, 28); |
|
| 1080 |
- memcpy(temp, &rom[0xa0], 16); // copy internal name |
|
| 1081 |
- temp[0x10] = rom[0xbe]; // reserved area (old checksum) |
|
| 1082 |
- temp[0x11] = rom[0xbf]; // reserved area (old checksum) |
|
| 1083 |
- temp[0x12] = rom[0xbd]; // complement check |
|
| 1084 |
- temp[0x13] = rom[0xb0]; // maker |
|
| 1085 |
- temp[0x14] = 1; // 1 save ? |
|
| 1086 |
- memcpy(&temp[0x1c], flashSaveMemory, saveSize); // copy save |
|
| 1087 |
- fwrite(temp, 1, totalSize, file); // write save + header |
|
| 1088 |
- u32 crc = 0; |
|
| 1089 |
- |
|
| 1090 |
- for(int i = 0; i < totalSize; i++) {
|
|
| 1091 |
- crc += ((u32)temp[i] << (crc % 0x18)); |
|
| 1092 |
- } |
|
| 1093 |
- |
|
| 1094 |
- utilPutDword(buffer, crc); |
|
| 1095 |
- fwrite(buffer, 1, 4, file); // CRC? |
|
| 1096 |
- |
|
| 1097 |
- fclose(file); |
|
| 1098 |
- delete [] temp; |
|
| 1099 |
- return true; |
|
| 1100 |
-} |
|
| 299 |
+ romSize = 0x2000000; |
|
| 1101 | 300 |
|
| 1102 |
-bool CPUImportEepromFile(const char *fileName) |
|
| 1103 |
-{
|
|
| 1104 |
- FILE *file = fopen(fileName, "rb"); |
|
| 1105 |
- |
|
| 1106 |
- if(!file) |
|
| 1107 |
- return false; |
|
| 1108 |
- |
|
| 1109 |
- // check file size to know what we should read |
|
| 1110 |
- fseek(file, 0, SEEK_END); |
|
| 1111 |
- |
|
| 1112 |
- long size = ftell(file); |
|
| 1113 |
- fseek(file, 0, SEEK_SET); |
|
| 1114 |
- if(size == 512 || size == 0x2000) {
|
|
| 1115 |
- if(fread(eepromData, 1, size, file) != (size_t)size) {
|
|
| 1116 |
- fclose(file); |
|
| 1117 |
- return false; |
|
| 1118 |
- } |
|
| 1119 |
- for(int i = 0; i < size;) {
|
|
| 1120 |
- u8 tmp = eepromData[i]; |
|
| 1121 |
- eepromData[i] = eepromData[7-i]; |
|
| 1122 |
- eepromData[7-i] = tmp; |
|
| 1123 |
- i++; |
|
| 1124 |
- tmp = eepromData[i]; |
|
| 1125 |
- eepromData[i] = eepromData[7-i]; |
|
| 1126 |
- eepromData[7-i] = tmp; |
|
| 1127 |
- i++; |
|
| 1128 |
- tmp = eepromData[i]; |
|
| 1129 |
- eepromData[i] = eepromData[7-i]; |
|
| 1130 |
- eepromData[7-i] = tmp; |
|
| 1131 |
- i++; |
|
| 1132 |
- tmp = eepromData[i]; |
|
| 1133 |
- eepromData[i] = eepromData[7-i]; |
|
| 1134 |
- eepromData[7-i] = tmp; |
|
| 1135 |
- i++; |
|
| 1136 |
- i += 4; |
|
| 1137 |
- } |
|
| 1138 |
- } else {
|
|
| 1139 |
- fclose(file); |
|
| 1140 |
- return false; |
|
| 1141 |
- } |
|
| 1142 |
- fclose(file); |
|
| 1143 |
- return true; |
|
| 1144 |
-} |
|
| 301 |
+ memset(&workRAM[0], 0, 0x40000); |
|
| 1145 | 302 |
|
| 1146 |
-bool CPUReadBatteryFile(const char *fileName) |
|
| 1147 |
-{
|
|
| 1148 |
- FILE *file = fopen(fileName, "rb"); |
|
| 1149 |
- |
|
| 1150 |
- if(!file) |
|
| 1151 |
- return false; |
|
| 1152 |
- |
|
| 1153 |
- // check file size to know what we should read |
|
| 1154 |
- fseek(file, 0, SEEK_END); |
|
| 1155 |
- |
|
| 1156 |
- long size = ftell(file); |
|
| 1157 |
- fseek(file, 0, SEEK_SET); |
|
| 1158 |
- systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 1159 |
- |
|
| 1160 |
- if(size == 512 || size == 0x2000) {
|
|
| 1161 |
- if(fread(eepromData, 1, size, file) != (size_t)size) {
|
|
| 1162 |
- fclose(file); |
|
| 1163 |
- return false; |
|
| 1164 |
- } |
|
| 1165 |
- } else {
|
|
| 1166 |
- if(size == 0x20000) {
|
|
| 1167 |
- if(fread(flashSaveMemory, 1, 0x20000, file) != 0x20000) {
|
|
| 1168 |
- fclose(file); |
|
| 1169 |
- return false; |
|
| 1170 |
- } |
|
| 1171 |
- flashSetSize(0x20000); |
|
| 1172 |
- } else {
|
|
| 1173 |
- if(fread(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
|
|
| 1174 |
- fclose(file); |
|
| 1175 |
- return false; |
|
| 1176 |
- } |
|
| 1177 |
- flashSetSize(0x10000); |
|
| 1178 |
- } |
|
| 1179 |
- } |
|
| 1180 |
- fclose(file); |
|
| 1181 |
- return true; |
|
| 1182 |
-} |
|
| 1183 |
- |
|
| 1184 |
-bool CPUWritePNGFile(const char *fileName) |
|
| 1185 |
-{
|
|
| 1186 |
- return utilWritePNGFile(fileName, 240, 160, pix); |
|
| 1187 |
-} |
|
| 1188 |
- |
|
| 1189 |
-bool CPUWriteBMPFile(const char *fileName) |
|
| 1190 |
-{
|
|
| 1191 |
- return utilWriteBMPFile(fileName, 240, 160, pix); |
|
| 1192 |
-}*/ |
|
| 1193 |
- |
|
| 1194 |
-bool CPUIsZipFile(const char * file) |
|
| 1195 |
-{
|
|
| 1196 |
- if(strlen(file) > 4) {
|
|
| 1197 |
- const char * p = strrchr(file,'.'); |
|
| 1198 |
- |
|
| 1199 |
- if(p != NULL) {
|
|
| 1200 |
- if(_stricmp(p, ".zip") == 0) |
|
| 1201 |
- return true; |
|
| 1202 |
- } |
|
| 1203 |
- } |
|
| 1204 |
- |
|
| 1205 |
- return false; |
|
| 1206 |
-} |
|
| 1207 |
- |
|
| 1208 |
-bool CPUIsGBAImage(const char * file) |
|
| 1209 |
-{
|
|
| 1210 |
- cpuIsMultiBoot = false; |
|
| 1211 |
- if(strlen(file) > 4) {
|
|
| 1212 |
- const char * p = strrchr(file,'.'); |
|
| 1213 |
- |
|
| 1214 |
- if(p != NULL) {
|
|
| 1215 |
- if(_stricmp(p, ".gba") == 0) |
|
| 1216 |
- return true; |
|
| 1217 |
- if(_stricmp(p, ".agb") == 0) |
|
| 1218 |
- return true; |
|
| 1219 |
- if(_stricmp(p, ".bin") == 0) |
|
| 1220 |
- return true; |
|
| 1221 |
- if(_stricmp(p, ".elf") == 0) |
|
| 1222 |
- return true; |
|
| 1223 |
- if(_stricmp(p, ".mb") == 0) {
|
|
| 1224 |
- cpuIsMultiBoot = true; |
|
| 1225 |
- return true; |
|
| 1226 |
- } |
|
| 1227 |
- } |
|
| 1228 |
- } |
|
| 1229 |
- |
|
| 1230 |
- return false; |
|
| 1231 |
-} |
|
| 1232 |
- |
|
| 1233 |
-bool CPUIsGBABios(const char * file) |
|
| 1234 |
-{
|
|
| 1235 |
- if(strlen(file) > 4) {
|
|
| 1236 |
- const char * p = strrchr(file,'.'); |
|
| 1237 |
- |
|
| 1238 |
- if(p != NULL) {
|
|
| 1239 |
- if(_stricmp(p, ".gba") == 0) |
|
| 1240 |
- return true; |
|
| 1241 |
- if(_stricmp(p, ".agb") == 0) |
|
| 1242 |
- return true; |
|
| 1243 |
- if(_stricmp(p, ".bin") == 0) |
|
| 1244 |
- return true; |
|
| 1245 |
- if(_stricmp(p, ".bios") == 0) |
|
| 1246 |
- return true; |
|
| 1247 |
- if(_stricmp(p, ".rom") == 0) |
|
| 1248 |
- return true; |
|
| 1249 |
- } |
|
| 1250 |
- } |
|
| 1251 |
- |
|
| 1252 |
- return false; |
|
| 1253 |
-} |
|
| 1254 |
- |
|
| 1255 |
-bool CPUIsELF(const char *file) |
|
| 1256 |
-{
|
|
| 1257 |
- if(file == NULL) |
|
| 1258 |
- return false; |
|
| 1259 |
- |
|
| 1260 |
- if(strlen(file) > 4) {
|
|
| 1261 |
- const char * p = strrchr(file,'.'); |
|
| 1262 |
- |
|
| 1263 |
- if(p != NULL) {
|
|
| 1264 |
- if(_stricmp(p, ".elf") == 0) |
|
| 1265 |
- return true; |
|
| 1266 |
- } |
|
| 1267 |
- } |
|
| 1268 |
- return false; |
|
| 1269 |
-} |
|
| 1270 |
- |
|
| 1271 |
-void CPUCleanUp() |
|
| 1272 |
-{
|
|
| 1273 |
-#ifdef PROFILING |
|
| 1274 |
- if(profilingTicksReload) {
|
|
| 1275 |
- profCleanup(); |
|
| 1276 |
- } |
|
| 1277 |
-#endif |
|
| 1278 |
- |
|
| 1279 |
- if(rom != NULL) {
|
|
| 1280 |
- free(rom); |
|
| 1281 |
- rom = NULL; |
|
| 1282 |
- } |
|
| 1283 |
- |
|
| 1284 |
- if(vram != NULL) {
|
|
| 1285 |
- free(vram); |
|
| 1286 |
- vram = NULL; |
|
| 1287 |
- } |
|
| 1288 |
- |
|
| 1289 |
- if(paletteRAM != NULL) {
|
|
| 1290 |
- free(paletteRAM); |
|
| 1291 |
- paletteRAM = NULL; |
|
| 1292 |
- } |
|
| 1293 |
- |
|
| 1294 |
- if(internalRAM != NULL) {
|
|
| 1295 |
- free(internalRAM); |
|
| 1296 |
- internalRAM = NULL; |
|
| 1297 |
- } |
|
| 1298 |
- |
|
| 1299 |
- if(workRAM != NULL) {
|
|
| 1300 |
- free(workRAM); |
|
| 1301 |
- workRAM = NULL; |
|
| 1302 |
- } |
|
| 1303 |
- |
|
| 1304 |
- if(bios != NULL) {
|
|
| 1305 |
- free(bios); |
|
| 1306 |
- bios = NULL; |
|
| 1307 |
- } |
|
| 1308 |
- |
|
| 1309 |
- if(pix != NULL) {
|
|
| 1310 |
- free(pix); |
|
| 1311 |
- pix = NULL; |
|
| 1312 |
- } |
|
| 1313 |
- |
|
| 1314 |
- if(oam != NULL) {
|
|
| 1315 |
- free(oam); |
|
| 1316 |
- oam = NULL; |
|
| 1317 |
- } |
|
| 1318 |
- |
|
| 1319 |
- if(ioMem != NULL) {
|
|
| 1320 |
- free(ioMem); |
|
| 1321 |
- ioMem = NULL; |
|
| 1322 |
- } |
|
| 1323 |
- |
|
| 1324 |
-#ifndef NO_DEBUGGER |
|
| 1325 |
- elfCleanUp(); |
|
| 1326 |
-#endif //NO_DEBUGGER |
|
| 1327 |
- |
|
| 1328 |
- //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 1329 |
- |
|
| 1330 |
- //emulating = 0; |
|
| 1331 |
-} |
|
| 1332 |
- |
|
| 1333 |
-int CPULoadRom(const char *szFile) |
|
| 1334 |
-{
|
|
| 1335 |
- romSize = 0x2000000; |
|
| 1336 |
- if(rom != NULL) {
|
|
| 1337 |
- CPUCleanUp(); |
|
| 1338 |
- } |
|
| 1339 |
- |
|
| 1340 |
- //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 1341 |
- |
|
| 1342 |
- rom = (uint8_t *)malloc(0x2000000); |
|
| 1343 |
- if(rom == NULL) {
|
|
| 1344 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1345 |
- "ROM");*/ |
|
| 1346 |
- return 0; |
|
| 1347 |
- } |
|
| 1348 |
- workRAM = (uint8_t *)calloc(1, 0x40000); |
|
| 1349 |
- if(workRAM == NULL) {
|
|
| 1350 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1351 |
- "WRAM");*/ |
|
| 1352 |
- return 0; |
|
| 1353 |
- } |
|
| 1354 |
- |
|
| 1355 |
- //u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom; |
|
| 1356 |
- |
|
| 1357 |
-#ifndef NO_DEBUGGER |
|
| 1358 |
- if(CPUIsELF(szFile)) {
|
|
| 1359 |
- FILE *f = fopen(szFile, "rb"); |
|
| 1360 |
- if(!f) {
|
|
| 1361 |
- systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"),
|
|
| 1362 |
- szFile); |
|
| 1363 |
- free(rom); |
|
| 1364 |
- rom = NULL; |
|
| 1365 |
- free(workRAM); |
|
| 1366 |
- workRAM = NULL; |
|
| 1367 |
- return 0; |
|
| 1368 |
- } |
|
| 1369 |
- bool res = elfRead(szFile, romSize, f); |
|
| 1370 |
- if(!res || romSize == 0) {
|
|
| 1371 |
- free(rom); |
|
| 1372 |
- rom = NULL; |
|
| 1373 |
- free(workRAM); |
|
| 1374 |
- workRAM = NULL; |
|
| 1375 |
- elfCleanUp(); |
|
| 1376 |
- return 0; |
|
| 1377 |
- } |
|
| 1378 |
- } else |
|
| 1379 |
-#endif //NO_DEBUGGER |
|
| 1380 |
- /*if(szFile!=NULL) |
|
| 1381 |
- {
|
|
| 1382 |
- if(!utilLoad(szFile, |
|
| 1383 |
- utilIsGBAImage, |
|
| 1384 |
- whereToLoad, |
|
| 1385 |
- romSize)) {
|
|
| 1386 |
- free(rom); |
|
| 1387 |
- rom = NULL; |
|
| 1388 |
- free(workRAM); |
|
| 1389 |
- workRAM = NULL; |
|
| 1390 |
- return 0; |
|
| 1391 |
- } |
|
| 1392 |
- }*/ |
|
| 1393 | 303 |
if (cpuIsMultiBoot) |
| 1394 |
- mapgsf(workRAM,0x40000,romSize); |
|
| 304 |
+ mapgsf(workRAM, 0x40000, romSize); |
|
| 1395 | 305 |
else |
| 1396 |
- mapgsf(rom, 0x2000000,romSize); |
|
| 1397 |
- |
|
| 1398 |
- uint16_t *temp = (uint16_t *)(rom+((romSize+1)&~1)); |
|
| 1399 |
- int i; |
|
| 1400 |
- for(i = (romSize+1)&~1; i < 0x2000000; i+=2) {
|
|
| 1401 |
- WRITE16LE(temp, (i >> 1) & 0xFFFF); |
|
| 1402 |
- temp++; |
|
| 1403 |
- } |
|
| 1404 |
- |
|
| 1405 |
- bios = (uint8_t *)calloc(1,0x4000); |
|
| 1406 |
- if(bios == NULL) {
|
|
| 1407 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1408 |
- "BIOS");*/ |
|
| 1409 |
- CPUCleanUp(); |
|
| 1410 |
- return 0; |
|
| 1411 |
- } |
|
| 1412 |
- internalRAM = (uint8_t *)calloc(1,0x8000); |
|
| 1413 |
- if(internalRAM == NULL) {
|
|
| 1414 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1415 |
- "IRAM");*/ |
|
| 1416 |
- CPUCleanUp(); |
|
| 1417 |
- return 0; |
|
| 1418 |
- } |
|
| 1419 |
- paletteRAM = (uint8_t *)calloc(1,0x400); |
|
| 1420 |
- if(paletteRAM == NULL) {
|
|
| 1421 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1422 |
- "PRAM");*/ |
|
| 1423 |
- CPUCleanUp(); |
|
| 1424 |
- return 0; |
|
| 1425 |
- } |
|
| 1426 |
- vram = (uint8_t *)calloc(1, 0x20000); |
|
| 1427 |
- if(vram == NULL) {
|
|
| 1428 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1429 |
- "VRAM");*/ |
|
| 1430 |
- CPUCleanUp(); |
|
| 1431 |
- return 0; |
|
| 1432 |
- } |
|
| 1433 |
- oam = (uint8_t *)calloc(1, 0x400); |
|
| 1434 |
- if(oam == NULL) {
|
|
| 1435 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1436 |
- "OAM");*/ |
|
| 1437 |
- CPUCleanUp(); |
|
| 1438 |
- return 0; |
|
| 1439 |
- } |
|
| 1440 |
- pix = (uint8_t *)calloc(1, 4 * 241 * 162); |
|
| 1441 |
- if(pix == NULL) {
|
|
| 1442 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1443 |
- "PIX");*/ |
|
| 1444 |
- CPUCleanUp(); |
|
| 1445 |
- return 0; |
|
| 1446 |
- } |
|
| 1447 |
- ioMem = (uint8_t *)calloc(1, 0x400); |
|
| 1448 |
- if(ioMem == NULL) {
|
|
| 1449 |
- /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1450 |
- "IO");*/ |
|
| 1451 |
- CPUCleanUp(); |
|
| 1452 |
- return 0; |
|
| 1453 |
- } |
|
| 1454 |
- |
|
| 1455 |
- //flashInit(); |
|
| 1456 |
- //eepromInit(); |
|
| 1457 |
- |
|
| 1458 |
- //CPUUpdateRenderBuffers(true); |
|
| 1459 |
- |
|
| 1460 |
- return romSize; |
|
| 306 |
+ mapgsf(rom, 0x2000000, romSize); |
|
| 307 |
+ |
|
| 308 |
+ uint16_t *temp = reinterpret_cast<uint16_t *>(rom + ((romSize + 1) & ~1)); |
|
| 309 |
+ int i; |
|
| 310 |
+ for (i = (romSize + 1) & ~1; i < 0x2000000; i += 2) |
|
| 311 |
+ {
|
|
| 312 |
+ WRITE16LE(temp, (i >> 1) & 0xFFFF); |
|
| 313 |
+ ++temp; |
|
| 314 |
+ } |
|
| 315 |
+ |
|
| 316 |
+ memset(&bios[0], 0, 0x4000); |
|
| 317 |
+ memset(&internalRAM[0], 0, 0x8000); |
|
| 318 |
+ memset(&paletteRAM[0], 0, 0x400); |
|
| 319 |
+ memset(&vram[0], 0, 0x20000); |
|
| 320 |
+ memset(&oam[0], 0, 0x400); |
|
| 321 |
+ memset(&ioMem[0], 0, 0x400); |
|
| 322 |
+ |
|
| 323 |
+ return romSize; |
|
| 1461 | 324 |
} |
| 1462 | 325 |
|
| 1463 |
-void doMirroring (bool b) |
|
| 1464 |
-{
|
|
| 1465 |
- uint32_t mirroredRomSize = (((romSize)>>20) & 0x3F)<<20; |
|
| 1466 |
- uint32_t mirroredRomAddress = romSize; |
|
| 1467 |
- if ((mirroredRomSize <=0x800000) && (b)) |
|
| 1468 |
- {
|
|
| 1469 |
- mirroredRomAddress = mirroredRomSize; |
|
| 1470 |
- if (mirroredRomSize==0) |
|
| 1471 |
- mirroredRomSize=0x100000; |
|
| 1472 |
- while (mirroredRomAddress<0x01000000) |
|
| 1473 |
- {
|
|
| 1474 |
- memcpy ((uint16_t *)(rom+mirroredRomAddress), (uint16_t *)(rom), mirroredRomSize); |
|
| 1475 |
- mirroredRomAddress+=mirroredRomSize; |
|
| 1476 |
- } |
|
| 1477 |
- } |
|
| 1478 |
-} |
|
| 1479 |
- |
|
| 1480 |
-/*void CPUUpdateRender() |
|
| 1481 |
-{
|
|
| 1482 |
- switch(DISPCNT & 7) {
|
|
| 1483 |
- case 0: |
|
| 1484 |
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1485 |
- cpuDisableSfx) |
|
| 1486 |
- renderLine = mode0RenderLine; |
|
| 1487 |
- else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1488 |
- renderLine = mode0RenderLineNoWindow; |
|
| 1489 |
- else |
|
| 1490 |
- renderLine = mode0RenderLineAll; |
|
| 1491 |
- break; |
|
| 1492 |
- case 1: |
|
| 1493 |
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1494 |
- cpuDisableSfx) |
|
| 1495 |
- renderLine = mode1RenderLine; |
|
| 1496 |
- else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1497 |
- renderLine = mode1RenderLineNoWindow; |
|
| 1498 |
- else |
|
| 1499 |
- renderLine = mode1RenderLineAll; |
|
| 1500 |
- break; |
|
| 1501 |
- case 2: |
|
| 1502 |
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1503 |
- cpuDisableSfx) |
|
| 1504 |
- renderLine = mode2RenderLine; |
|
| 1505 |
- else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1506 |
- renderLine = mode2RenderLineNoWindow; |
|
| 1507 |
- else |
|
| 1508 |
- renderLine = mode2RenderLineAll; |
|
| 1509 |
- break; |
|
| 1510 |
- case 3: |
|
| 1511 |
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1512 |
- cpuDisableSfx) |
|
| 1513 |
- renderLine = mode3RenderLine; |
|
| 1514 |
- else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1515 |
- renderLine = mode3RenderLineNoWindow; |
|
| 1516 |
- else |
|
| 1517 |
- renderLine = mode3RenderLineAll; |
|
| 1518 |
- break; |
|
| 1519 |
- case 4: |
|
| 1520 |
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1521 |
- cpuDisableSfx) |
|
| 1522 |
- renderLine = mode4RenderLine; |
|
| 1523 |
- else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1524 |
- renderLine = mode4RenderLineNoWindow; |
|
| 1525 |
- else |
|
| 1526 |
- renderLine = mode4RenderLineAll; |
|
| 1527 |
- break; |
|
| 1528 |
- case 5: |
|
| 1529 |
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1530 |
- cpuDisableSfx) |
|
| 1531 |
- renderLine = mode5RenderLine; |
|
| 1532 |
- else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1533 |
- renderLine = mode5RenderLineNoWindow; |
|
| 1534 |
- else |
|
| 1535 |
- renderLine = mode5RenderLineAll; |
|
| 1536 |
- default: |
|
| 1537 |
- break; |
|
| 1538 |
- } |
|
| 1539 |
-}*/ |
|
| 1540 |
- |
|
| 1541 | 326 |
void CPUUpdateCPSR() |
| 1542 | 327 |
{
|
| 1543 |
- uint32_t CPSR = reg[16].I & 0x40; |
|
| 1544 |
- if(N_FLAG) |
|
| 1545 |
- CPSR |= 0x80000000; |
|
| 1546 |
- if(Z_FLAG) |
|
| 1547 |
- CPSR |= 0x40000000; |
|
| 1548 |
- if(C_FLAG) |
|
| 1549 |
- CPSR |= 0x20000000; |
|
| 1550 |
- if(V_FLAG) |
|
| 1551 |
- CPSR |= 0x10000000; |
|
| 1552 |
- if(!armState) |
|
| 1553 |
- CPSR |= 0x00000020; |
|
| 1554 |
- if(!armIrqEnable) |
|
| 1555 |
- CPSR |= 0x80; |
|
| 1556 |
- CPSR |= (armMode & 0x1F); |
|
| 1557 |
- reg[16].I = CPSR; |
|
| 328 |
+ uint32_t CPSR = reg[16].I & 0x40; |
|
| 329 |
+ if (N_FLAG) |
|
| 330 |
+ CPSR |= 0x80000000; |
|
| 331 |
+ if (Z_FLAG) |
|
| 332 |
+ CPSR |= 0x40000000; |
|
| 333 |
+ if (C_FLAG) |
|
| 334 |
+ CPSR |= 0x20000000; |
|
| 335 |
+ if (V_FLAG) |
|
| 336 |
+ CPSR |= 0x10000000; |
|
| 337 |
+ if (!armState) |
|
| 338 |
+ CPSR |= 0x00000020; |
|
| 339 |
+ if (!armIrqEnable) |
|
| 340 |
+ CPSR |= 0x80; |
|
| 341 |
+ CPSR |= armMode & 0x1F; |
|
| 342 |
+ reg[16].I = CPSR; |
|
| 1558 | 343 |
} |
| 1559 | 344 |
|
| 1560 | 345 |
void CPUUpdateFlags(bool breakLoop) |
| 1561 | 346 |
{
|
| 1562 |
- uint32_t CPSR = reg[16].I; |
|
| 1563 |
- |
|
| 1564 |
- N_FLAG = (CPSR & 0x80000000) ? true: false; |
|
| 1565 |
- Z_FLAG = (CPSR & 0x40000000) ? true: false; |
|
| 1566 |
- C_FLAG = (CPSR & 0x20000000) ? true: false; |
|
| 1567 |
- V_FLAG = (CPSR & 0x10000000) ? true: false; |
|
| 1568 |
- armState = (CPSR & 0x20) ? false : true; |
|
| 1569 |
- armIrqEnable = (CPSR & 0x80) ? false : true; |
|
| 1570 |
- if(breakLoop) {
|
|
| 1571 |
- if (armIrqEnable && (IF & IE) && (IME & 1)) |
|
| 1572 |
- cpuNextEvent = cpuTotalTicks; |
|
| 1573 |
- } |
|
| 1574 |
-} |
|
| 1575 |
- |
|
| 1576 |
-void CPUUpdateFlags() |
|
| 1577 |
-{
|
|
| 1578 |
- CPUUpdateFlags(true); |
|
| 347 |
+ uint32_t CPSR = reg[16].I; |
|
| 348 |
+ |
|
| 349 |
+ N_FLAG = !!(CPSR & 0x80000000); |
|
| 350 |
+ Z_FLAG = !!(CPSR & 0x40000000); |
|
| 351 |
+ C_FLAG = !!(CPSR & 0x20000000); |
|
| 352 |
+ V_FLAG = !!(CPSR & 0x10000000); |
|
| 353 |
+ armState = !(CPSR & 0x20); |
|
| 354 |
+ armIrqEnable = !(CPSR & 0x80); |
|
| 355 |
+ if (breakLoop && armIrqEnable && (IF & IE) && (IME & 1)) |
|
| 356 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1579 | 357 |
} |
| 1580 | 358 |
|
| 1581 |
-#ifdef WORDS_BIGENDIAN |
|
| 1582 |
-static void CPUSwap(volatile uint32_t *a, volatile uint32_t *b) |
|
| 1583 |
-{
|
|
| 1584 |
- volatile uint32_t c = *b; |
|
| 1585 |
- *b = *a; |
|
| 1586 |
- *a = c; |
|
| 1587 |
-} |
|
| 1588 |
-#else |
|
| 1589 |
-static void CPUSwap(uint32_t *a, uint32_t *b) |
|
| 1590 |
-{
|
|
| 1591 |
- uint32_t c = *b; |
|
| 1592 |
- *b = *a; |
|
| 1593 |
- *a = c; |
|
| 1594 |
-} |
|
| 1595 |
-#endif |
|
| 1596 |
- |
|
| 1597 | 359 |
void CPUSwitchMode(int mode, bool saveState, bool breakLoop) |
| 1598 | 360 |
{
|
| 1599 |
- // if(armMode == mode) |
|
| 1600 |
- // return; |
|
| 1601 |
- |
|
| 1602 |
- CPUUpdateCPSR(); |
|
| 1603 |
- |
|
| 1604 |
- switch(armMode) {
|
|
| 1605 |
- case 0x10: |
|
| 1606 |
- case 0x1F: |
|
| 1607 |
- reg[R13_USR].I = reg[13].I; |
|
| 1608 |
- reg[R14_USR].I = reg[14].I; |
|
| 1609 |
- reg[17].I = reg[16].I; |
|
| 1610 |
- break; |
|
| 1611 |
- case 0x11: |
|
| 1612 |
- CPUSwap(®[R8_FIQ].I, ®[8].I); |
|
| 1613 |
- CPUSwap(®[R9_FIQ].I, ®[9].I); |
|
| 1614 |
- CPUSwap(®[R10_FIQ].I, ®[10].I); |
|
| 1615 |
- CPUSwap(®[R11_FIQ].I, ®[11].I); |
|
| 1616 |
- CPUSwap(®[R12_FIQ].I, ®[12].I); |
|
| 1617 |
- reg[R13_FIQ].I = reg[13].I; |
|
| 1618 |
- reg[R14_FIQ].I = reg[14].I; |
|
| 1619 |
- reg[SPSR_FIQ].I = reg[17].I; |
|
| 1620 |
- break; |
|
| 1621 |
- case 0x12: |
|
| 1622 |
- reg[R13_IRQ].I = reg[13].I; |
|
| 1623 |
- reg[R14_IRQ].I = reg[14].I; |
|
| 1624 |
- reg[SPSR_IRQ].I = reg[17].I; |
|
| 1625 |
- break; |
|
| 1626 |
- case 0x13: |
|
| 1627 |
- reg[R13_SVC].I = reg[13].I; |
|
| 1628 |
- reg[R14_SVC].I = reg[14].I; |
|
| 1629 |
- reg[SPSR_SVC].I = reg[17].I; |
|
| 1630 |
- break; |
|
| 1631 |
- case 0x17: |
|
| 1632 |
- reg[R13_ABT].I = reg[13].I; |
|
| 1633 |
- reg[R14_ABT].I = reg[14].I; |
|
| 1634 |
- reg[SPSR_ABT].I = reg[17].I; |
|
| 1635 |
- break; |
|
| 1636 |
- case 0x1b: |
|
| 1637 |
- reg[R13_UND].I = reg[13].I; |
|
| 1638 |
- reg[R14_UND].I = reg[14].I; |
|
| 1639 |
- reg[SPSR_UND].I = reg[17].I; |
|
| 1640 |
- break; |
|
| 1641 |
- } |
|
| 1642 |
- |
|
| 1643 |
- uint32_t CPSR = reg[16].I; |
|
| 1644 |
- uint32_t SPSR = reg[17].I; |
|
| 1645 |
- |
|
| 1646 |
- switch(mode) {
|
|
| 1647 |
- case 0x10: |
|
| 1648 |
- case 0x1F: |
|
| 1649 |
- reg[13].I = reg[R13_USR].I; |
|
| 1650 |
- reg[14].I = reg[R14_USR].I; |
|
| 1651 |
- reg[16].I = SPSR; |
|
| 1652 |
- break; |
|
| 1653 |
- case 0x11: |
|
| 1654 |
- CPUSwap(®[8].I, ®[R8_FIQ].I); |
|
| 1655 |
- CPUSwap(®[9].I, ®[R9_FIQ].I); |
|
| 1656 |
- CPUSwap(®[10].I, ®[R10_FIQ].I); |
|
| 1657 |
- CPUSwap(®[11].I, ®[R11_FIQ].I); |
|
| 1658 |
- CPUSwap(®[12].I, ®[R12_FIQ].I); |
|
| 1659 |
- reg[13].I = reg[R13_FIQ].I; |
|
| 1660 |
- reg[14].I = reg[R14_FIQ].I; |
|
| 1661 |
- if(saveState) |
|
| 1662 |
- reg[17].I = CPSR; |
|
| 1663 |
- else |
|
| 1664 |
- reg[17].I = reg[SPSR_FIQ].I; |
|
| 1665 |
- break; |
|
| 1666 |
- case 0x12: |
|
| 1667 |
- reg[13].I = reg[R13_IRQ].I; |
|
| 1668 |
- reg[14].I = reg[R14_IRQ].I; |
|
| 1669 |
- reg[16].I = SPSR; |
|
| 1670 |
- if(saveState) |
|
| 1671 |
- reg[17].I = CPSR; |
|
| 1672 |
- else |
|
| 1673 |
- reg[17].I = reg[SPSR_IRQ].I; |
|
| 1674 |
- break; |
|
| 1675 |
- case 0x13: |
|
| 1676 |
- reg[13].I = reg[R13_SVC].I; |
|
| 1677 |
- reg[14].I = reg[R14_SVC].I; |
|
| 1678 |
- reg[16].I = SPSR; |
|
| 1679 |
- if(saveState) |
|
| 1680 |
- reg[17].I = CPSR; |
|
| 1681 |
- else |
|
| 1682 |
- reg[17].I = reg[SPSR_SVC].I; |
|
| 1683 |
- break; |
|
| 1684 |
- case 0x17: |
|
| 1685 |
- reg[13].I = reg[R13_ABT].I; |
|
| 1686 |
- reg[14].I = reg[R14_ABT].I; |
|
| 1687 |
- reg[16].I = SPSR; |
|
| 1688 |
- if(saveState) |
|
| 1689 |
- reg[17].I = CPSR; |
|
| 1690 |
- else |
|
| 1691 |
- reg[17].I = reg[SPSR_ABT].I; |
|
| 1692 |
- break; |
|
| 1693 |
- case 0x1b: |
|
| 1694 |
- reg[13].I = reg[R13_UND].I; |
|
| 1695 |
- reg[14].I = reg[R14_UND].I; |
|
| 1696 |
- reg[16].I = SPSR; |
|
| 1697 |
- if(saveState) |
|
| 1698 |
- reg[17].I = CPSR; |
|
| 1699 |
- else |
|
| 1700 |
- reg[17].I = reg[SPSR_UND].I; |
|
| 1701 |
- break; |
|
| 1702 |
- default: |
|
| 1703 |
- //systemMessage(MSG_UNSUPPORTED_ARM_MODE, N_("Unsupported ARM mode %02x"), mode);
|
|
| 1704 |
- break; |
|
| 1705 |
- } |
|
| 1706 |
- armMode = mode; |
|
| 1707 |
- CPUUpdateFlags(breakLoop); |
|
| 1708 |
- CPUUpdateCPSR(); |
|
| 1709 |
-} |
|
| 1710 |
- |
|
| 1711 |
-void CPUSwitchMode(int mode, bool saveState) |
|
| 1712 |
-{
|
|
| 1713 |
- CPUSwitchMode(mode, saveState, true); |
|
| 361 |
+ CPUUpdateCPSR(); |
|
| 362 |
+ |
|
| 363 |
+ switch (armMode) |
|
| 364 |
+ {
|
|
| 365 |
+ case 0x10: |
|
| 366 |
+ case 0x1F: |
|
| 367 |
+ reg[R13_USR].I = reg[13].I; |
|
| 368 |
+ reg[R14_USR].I = reg[14].I; |
|
| 369 |
+ reg[17].I = reg[16].I; |
|
| 370 |
+ break; |
|
| 371 |
+ case 0x11: |
|
| 372 |
+ std::swap(reg[R8_FIQ].I, reg[8].I); |
|
| 373 |
+ std::swap(reg[R9_FIQ].I, reg[9].I); |
|
| 374 |
+ std::swap(reg[R10_FIQ].I, reg[10].I); |
|
| 375 |
+ std::swap(reg[R11_FIQ].I, reg[11].I); |
|
| 376 |
+ std::swap(reg[R12_FIQ].I, reg[12].I); |
|
| 377 |
+ reg[R13_FIQ].I = reg[13].I; |
|
| 378 |
+ reg[R14_FIQ].I = reg[14].I; |
|
| 379 |
+ reg[SPSR_FIQ].I = reg[17].I; |
|
| 380 |
+ break; |
|
| 381 |
+ case 0x12: |
|
| 382 |
+ reg[R13_IRQ].I = reg[13].I; |
|
| 383 |
+ reg[R14_IRQ].I = reg[14].I; |
|
| 384 |
+ reg[SPSR_IRQ].I = reg[17].I; |
|
| 385 |
+ break; |
|
| 386 |
+ case 0x13: |
|
| 387 |
+ reg[R13_SVC].I = reg[13].I; |
|
| 388 |
+ reg[R14_SVC].I = reg[14].I; |
|
| 389 |
+ reg[SPSR_SVC].I = reg[17].I; |
|
| 390 |
+ break; |
|
| 391 |
+ case 0x17: |
|
| 392 |
+ reg[R13_ABT].I = reg[13].I; |
|
| 393 |
+ reg[R14_ABT].I = reg[14].I; |
|
| 394 |
+ reg[SPSR_ABT].I = reg[17].I; |
|
| 395 |
+ break; |
|
| 396 |
+ case 0x1b: |
|
| 397 |
+ reg[R13_UND].I = reg[13].I; |
|
| 398 |
+ reg[R14_UND].I = reg[14].I; |
|
| 399 |
+ reg[SPSR_UND].I = reg[17].I; |
|
| 400 |
+ } |
|
| 401 |
+ |
|
| 402 |
+ uint32_t CPSR = reg[16].I; |
|
| 403 |
+ uint32_t SPSR = reg[17].I; |
|
| 404 |
+ |
|
| 405 |
+ switch (mode) |
|
| 406 |
+ {
|
|
| 407 |
+ case 0x10: |
|
| 408 |
+ case 0x1F: |
|
| 409 |
+ reg[13].I = reg[R13_USR].I; |
|
| 410 |
+ reg[14].I = reg[R14_USR].I; |
|
| 411 |
+ reg[16].I = SPSR; |
|
| 412 |
+ break; |
|
| 413 |
+ case 0x11: |
|
| 414 |
+ std::swap(reg[8].I, reg[R8_FIQ].I); |
|
| 415 |
+ std::swap(reg[9].I, reg[R9_FIQ].I); |
|
| 416 |
+ std::swap(reg[10].I, reg[R10_FIQ].I); |
|
| 417 |
+ std::swap(reg[11].I, reg[R11_FIQ].I); |
|
| 418 |
+ std::swap(reg[12].I, reg[R12_FIQ].I); |
|
| 419 |
+ reg[13].I = reg[R13_FIQ].I; |
|
| 420 |
+ reg[14].I = reg[R14_FIQ].I; |
|
| 421 |
+ if (saveState) |
|
| 422 |
+ reg[17].I = CPSR; |
|
| 423 |
+ else |
|
| 424 |
+ reg[17].I = reg[SPSR_FIQ].I; |
|
| 425 |
+ break; |
|
| 426 |
+ case 0x12: |
|
| 427 |
+ reg[13].I = reg[R13_IRQ].I; |
|
| 428 |
+ reg[14].I = reg[R14_IRQ].I; |
|
| 429 |
+ reg[16].I = SPSR; |
|
| 430 |
+ if (saveState) |
|
| 431 |
+ reg[17].I = CPSR; |
|
| 432 |
+ else |
|
| 433 |
+ reg[17].I = reg[SPSR_IRQ].I; |
|
| 434 |
+ break; |
|
| 435 |
+ case 0x13: |
|
| 436 |
+ reg[13].I = reg[R13_SVC].I; |
|
| 437 |
+ reg[14].I = reg[R14_SVC].I; |
|
| 438 |
+ reg[16].I = SPSR; |
|
| 439 |
+ if (saveState) |
|
| 440 |
+ reg[17].I = CPSR; |
|
| 441 |
+ else |
|
| 442 |
+ reg[17].I = reg[SPSR_SVC].I; |
|
| 443 |
+ break; |
|
| 444 |
+ case 0x17: |
|
| 445 |
+ reg[13].I = reg[R13_ABT].I; |
|
| 446 |
+ reg[14].I = reg[R14_ABT].I; |
|
| 447 |
+ reg[16].I = SPSR; |
|
| 448 |
+ if (saveState) |
|
| 449 |
+ reg[17].I = CPSR; |
|
| 450 |
+ else |
|
| 451 |
+ reg[17].I = reg[SPSR_ABT].I; |
|
| 452 |
+ break; |
|
| 453 |
+ case 0x1b: |
|
| 454 |
+ reg[13].I = reg[R13_UND].I; |
|
| 455 |
+ reg[14].I = reg[R14_UND].I; |
|
| 456 |
+ reg[16].I = SPSR; |
|
| 457 |
+ if (saveState) |
|
| 458 |
+ reg[17].I = CPSR; |
|
| 459 |
+ else |
|
| 460 |
+ reg[17].I = reg[SPSR_UND].I; |
|
| 461 |
+ } |
|
| 462 |
+ armMode = mode; |
|
| 463 |
+ CPUUpdateFlags(breakLoop); |
|
| 464 |
+ CPUUpdateCPSR(); |
|
| 1714 | 465 |
} |
| 1715 | 466 |
|
| 1716 | 467 |
void CPUUndefinedException() |
| 1717 | 468 |
{
|
| 1718 |
- uint32_t PC = reg[15].I; |
|
| 1719 |
- bool savedArmState = armState; |
|
| 1720 |
- CPUSwitchMode(0x1b, true, false); |
|
| 1721 |
- reg[14].I = PC - (savedArmState ? 4 : 2); |
|
| 1722 |
- reg[15].I = 0x04; |
|
| 1723 |
- armState = true; |
|
| 1724 |
- armIrqEnable = false; |
|
| 1725 |
- armNextPC = 0x04; |
|
| 1726 |
- ARM_PREFETCH; |
|
| 1727 |
- reg[15].I += 4; |
|
| 469 |
+ uint32_t PC = reg[15].I; |
|
| 470 |
+ bool savedArmState = armState; |
|
| 471 |
+ CPUSwitchMode(0x1b, true, false); |
|
| 472 |
+ reg[14].I = PC - (savedArmState ? 4 : 2); |
|
| 473 |
+ reg[15].I = 0x04; |
|
| 474 |
+ armState = true; |
|
| 475 |
+ armIrqEnable = false; |
|
| 476 |
+ armNextPC = 0x04; |
|
| 477 |
+ ARM_PREFETCH(); |
|
| 478 |
+ reg[15].I += 4; |
|
| 1728 | 479 |
} |
| 1729 | 480 |
|
| 1730 | 481 |
void CPUSoftwareInterrupt() |
| 1731 | 482 |
{
|
| 1732 |
- uint32_t PC = reg[15].I; |
|
| 1733 |
- bool savedArmState = armState; |
|
| 1734 |
- CPUSwitchMode(0x13, true, false); |
|
| 1735 |
- reg[14].I = PC - (savedArmState ? 4 : 2); |
|
| 1736 |
- reg[15].I = 0x08; |
|
| 1737 |
- armState = true; |
|
| 1738 |
- armIrqEnable = false; |
|
| 1739 |
- armNextPC = 0x08; |
|
| 1740 |
- ARM_PREFETCH; |
|
| 1741 |
- reg[15].I += 4; |
|
| 483 |
+ uint32_t PC = reg[15].I; |
|
| 484 |
+ bool savedArmState = armState; |
|
| 485 |
+ CPUSwitchMode(0x13, true, false); |
|
| 486 |
+ reg[14].I = PC - (savedArmState ? 4 : 2); |
|
| 487 |
+ reg[15].I = 0x08; |
|
| 488 |
+ armState = true; |
|
| 489 |
+ armIrqEnable = false; |
|
| 490 |
+ armNextPC = 0x08; |
|
| 491 |
+ ARM_PREFETCH(); |
|
| 492 |
+ reg[15].I += 4; |
|
| 1742 | 493 |
} |
| 1743 | 494 |
|
| 1744 | 495 |
void CPUSoftwareInterrupt(int comment) |
| 1745 | 496 |
{
|
| 1746 |
- static bool disableMessage = false; |
|
| 1747 |
- if(armState) comment >>= 16; |
|
| 1748 |
-#ifdef BKPT_SUPPORT |
|
| 1749 |
- if(comment == 0xff) {
|
|
| 1750 |
- dbgOutput(NULL, reg[0].I); |
|
| 1751 |
- return; |
|
| 1752 |
- } |
|
| 1753 |
-#endif |
|
| 1754 |
-#ifdef PROFILING |
|
| 1755 |
- if(comment == 0xfe) {
|
|
| 1756 |
- profStartup(reg[0].I, reg[1].I); |
|
| 1757 |
- return; |
|
| 1758 |
- } |
|
| 1759 |
- if(comment == 0xfd) {
|
|
| 1760 |
- profControl(reg[0].I); |
|
| 1761 |
- return; |
|
| 1762 |
- } |
|
| 1763 |
- if(comment == 0xfc) {
|
|
| 1764 |
- profCleanup(); |
|
| 1765 |
- return; |
|
| 1766 |
- } |
|
| 1767 |
- if(comment == 0xfb) {
|
|
| 1768 |
- profCount(); |
|
| 1769 |
- return; |
|
| 1770 |
- } |
|
| 1771 |
-#endif |
|
| 1772 |
- if(comment == 0xfa) {
|
|
| 1773 |
- //agbPrintFlush(); |
|
| 1774 |
- return; |
|
| 1775 |
- } |
|
| 1776 |
-#ifdef SDL |
|
| 1777 |
- if(comment == 0xf9) {
|
|
| 1778 |
- emulating = 0; |
|
| 1779 |
- cpuNextEvent = cpuTotalTicks; |
|
| 1780 |
- cpuBreakLoop = true; |
|
| 1781 |
- return; |
|
| 1782 |
- } |
|
| 1783 |
-#endif |
|
| 1784 |
- if(useBios) {
|
|
| 1785 |
-#ifdef GBA_LOGGING |
|
| 1786 |
- if(systemVerbose & VERBOSE_SWI) {
|
|
| 1787 |
- log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
|
| 1788 |
- armState ? armNextPC - 4: armNextPC -2, |
|
| 1789 |
- reg[0].I, |
|
| 1790 |
- reg[1].I, |
|
| 1791 |
- reg[2].I, |
|
| 1792 |
- VCOUNT); |
|
| 1793 |
- } |
|
| 1794 |
-#endif |
|
| 1795 |
- CPUSoftwareInterrupt(); |
|
| 1796 |
- return; |
|
| 1797 |
- } |
|
| 1798 |
- // This would be correct, but it causes problems if uncommented |
|
| 1799 |
- // else {
|
|
| 1800 |
- // biosProtected = 0xe3a02004; |
|
| 1801 |
- // } |
|
| 1802 |
- |
|
| 1803 |
- switch(comment) {
|
|
| 1804 |
- case 0x00: |
|
| 1805 |
- BIOS_SoftReset(); |
|
| 1806 |
- ARM_PREFETCH; |
|
| 1807 |
- break; |
|
| 1808 |
- case 0x01: |
|
| 1809 |
- BIOS_RegisterRamReset(); |
|
| 1810 |
- break; |
|
| 1811 |
- case 0x02: |
|
| 1812 |
-#ifdef GBA_LOGGING |
|
| 1813 |
- if(systemVerbose & VERBOSE_SWI) {
|
|
| 1814 |
- /*log("Halt: (VCOUNT = %2d)\n",
|
|
| 1815 |
- VCOUNT);*/ |
|
| 1816 |
- } |
|
| 1817 |
-#endif |
|
| 1818 |
- holdState = true; |
|
| 1819 |
- holdType = -1; |
|
| 1820 |
- cpuNextEvent = cpuTotalTicks; |
|
| 1821 |
- break; |
|
| 1822 |
- case 0x03: |
|
| 1823 |
-#ifdef GBA_LOGGING |
|
| 1824 |
- if(systemVerbose & VERBOSE_SWI) {
|
|
| 1825 |
- /*log("Stop: (VCOUNT = %2d)\n",
|
|
| 1826 |
- VCOUNT);*/ |
|
| 1827 |
- } |
|
| 1828 |
-#endif |
|
| 1829 |
- /*holdState = true; |
|
| 1830 |
- holdType = -1; |
|
| 1831 |
- stopState = true; |
|
| 1832 |
- cpuNextEvent = cpuTotalTicks;*/ |
|
| 1833 |
- break; |
|
| 1834 |
- case 0x04: |
|
| 1835 |
-#ifdef GBA_LOGGING |
|
| 1836 |
- if(systemVerbose & VERBOSE_SWI) {
|
|
| 1837 |
- log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n",
|
|
| 1838 |
- reg[0].I, |
|
| 1839 |
- reg[1].I, |
|
| 1840 |
- VCOUNT); |
|
| 1841 |
- } |
|
| 1842 |
-#endif |
|
| 1843 |
- CPUSoftwareInterrupt(); |
|
| 1844 |
- break; |
|
| 1845 |
- case 0x05: |
|
| 1846 |
-#ifdef GBA_LOGGING |
|
| 1847 |
- if(systemVerbose & VERBOSE_SWI) {
|
|
| 1848 |
- log("VBlankIntrWait: (VCOUNT = %2d)\n",
|
|
| 1849 |
- VCOUNT); |
|
| 1850 |
- } |
|
| 1851 |
-#endif |
|
| 1852 |
- CPUSoftwareInterrupt(); |
|
| 1853 |
- break; |
|
| 1854 |
- case 0x06: |
|
| 1855 |
- CPUSoftwareInterrupt(); |
|
| 1856 |
- break; |
|
| 1857 |
- case 0x07: |
|
| 1858 |
- CPUSoftwareInterrupt(); |
|
| 1859 |
- break; |
|
| 1860 |
- case 0x08: |
|
| 1861 |
- BIOS_Sqrt(); |
|
| 1862 |
- break; |
|
| 1863 |
- case 0x09: |
|
| 1864 |
- BIOS_ArcTan(); |
|
| 1865 |
- break; |
|
| 1866 |
- case 0x0A: |
|
| 1867 |
- BIOS_ArcTan2(); |
|
| 1868 |
- break; |
|
| 1869 |
- case 0x0B: |
|
| 1870 |
- {
|
|
| 1871 |
- int len = (reg[2].I & 0x1FFFFF) >>1; |
|
| 1872 |
- if (!(((reg[0].I & 0xe000000) == 0) || |
|
| 1873 |
- ((reg[0].I + len) & 0xe000000) == 0)) |
|
| 1874 |
- {
|
|
| 1875 |
- if ((reg[2].I >> 24) & 1) |
|
| 1876 |
- {
|
|
| 1877 |
- if ((reg[2].I >> 26) & 1) |
|
| 1878 |
- SWITicks = (7 + memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1); |
|
| 1879 |
- else |
|
| 1880 |
- SWITicks = (8 + memoryWait[(reg[1].I>>24) & 0xF]) * (len); |
|
| 1881 |
- } |
|
| 1882 |
- else |
|
| 1883 |
- {
|
|
| 1884 |
- if ((reg[2].I >> 26) & 1) |
|
| 1885 |
- SWITicks = (10 + memoryWait32[(reg[0].I>>24) & 0xF] + |
|
| 1886 |
- memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1); |
|
| 1887 |
- else |
|
| 1888 |
- SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] + |
|
| 1889 |
- memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1890 |
- } |
|
| 1891 |
- } |
|
| 1892 |
- } |
|
| 1893 |
- BIOS_CpuSet(); |
|
| 1894 |
- break; |
|
| 1895 |
- case 0x0C: |
|
| 1896 |
- {
|
|
| 1897 |
- int len = (reg[2].I & 0x1FFFFF) >>5; |
|
| 1898 |
- if (!(((reg[0].I & 0xe000000) == 0) || |
|
| 1899 |
- ((reg[0].I + len) & 0xe000000) == 0)) |
|
| 1900 |
- {
|
|
| 1901 |
- if ((reg[2].I >> 24) & 1) |
|
| 1902 |
- SWITicks = (6 + memoryWait32[(reg[1].I>>24) & 0xF] + |
|
| 1903 |
- 7 * (memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 1)) * len; |
|
| 1904 |
- else |
|
| 1905 |
- SWITicks = (9 + memoryWait32[(reg[0].I>>24) & 0xF] + |
|
| 1906 |
- memoryWait32[(reg[1].I>>24) & 0xF] + |
|
| 1907 |
- 7 * (memoryWaitSeq32[(reg[0].I>>24) & 0xF] + |
|
| 1908 |
- memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 2)) * len; |
|
| 1909 |
- } |
|
| 1910 |
- } |
|
| 1911 |
- BIOS_CpuFastSet(); |
|
| 1912 |
- break; |
|
| 1913 |
- case 0x0D: |
|
| 1914 |
- BIOS_GetBiosChecksum(); |
|
| 1915 |
- break; |
|
| 1916 |
- case 0x0E: |
|
| 1917 |
- BIOS_BgAffineSet(); |
|
| 1918 |
- break; |
|
| 1919 |
- case 0x0F: |
|
| 1920 |
- BIOS_ObjAffineSet(); |
|
| 1921 |
- break; |
|
| 1922 |
- case 0x10: |
|
| 1923 |
- {
|
|
| 1924 |
- int len = CPUReadHalfWord(reg[2].I); |
|
| 1925 |
- if (!(((reg[0].I & 0xe000000) == 0) || |
|
| 1926 |
- ((reg[0].I + len) & 0xe000000) == 0)) |
|
| 1927 |
- SWITicks = (32 + memoryWait[(reg[0].I>>24) & 0xF]) * len; |
|
| 1928 |
- } |
|
| 1929 |
- BIOS_BitUnPack(); |
|
| 1930 |
- break; |
|
| 1931 |
- case 0x11: |
|
| 1932 |
- {
|
|
| 1933 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1934 |
- if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1935 |
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1936 |
- SWITicks = (9 + memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1937 |
- } |
|
| 1938 |
- BIOS_LZ77UnCompWram(); |
|
| 1939 |
- break; |
|
| 1940 |
- case 0x12: |
|
| 1941 |
- {
|
|
| 1942 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1943 |
- if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1944 |
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1945 |
- SWITicks = (19 + memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1946 |
- } |
|
| 1947 |
- BIOS_LZ77UnCompVram(); |
|
| 1948 |
- break; |
|
| 1949 |
- case 0x13: |
|
| 1950 |
- {
|
|
| 1951 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1952 |
- if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1953 |
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1954 |
- SWITicks = (29 + (memoryWait[(reg[0].I>>24) & 0xF]<<1)) * len; |
|
| 1955 |
- } |
|
| 1956 |
- BIOS_HuffUnComp(); |
|
| 1957 |
- break; |
|
| 1958 |
- case 0x14: |
|
| 1959 |
- {
|
|
| 1960 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1961 |
- if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1962 |
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1963 |
- SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] + |
|
| 1964 |
- memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1965 |
- } |
|
| 1966 |
- BIOS_RLUnCompWram(); |
|
| 1967 |
- break; |
|
| 1968 |
- case 0x15: |
|
| 1969 |
- {
|
|
| 1970 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 1971 |
- if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1972 |
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1973 |
- SWITicks = (34 + (memoryWait[(reg[0].I>>24) & 0xF] << 1) + |
|
| 1974 |
- memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1975 |
- } |
|
| 1976 |
- BIOS_RLUnCompVram(); |
|
| 1977 |
- break; |
|
| 1978 |
- case 0x16: |
|
| 1979 |
- {
|
|
| 1980 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1981 |
- if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1982 |
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1983 |
- SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] + |
|
| 1984 |
- memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1985 |
- } |
|
| 1986 |
- BIOS_Diff8bitUnFilterWram(); |
|
| 1987 |
- break; |
|
| 1988 |
- case 0x17: |
|
| 1989 |
- {
|
|
| 1990 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 1991 |
- if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1992 |
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1993 |
- SWITicks = (39 + (memoryWait[(reg[0].I>>24) & 0xF]<<1) + |
|
| 1994 |
- memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1995 |
- } |
|
| 1996 |
- BIOS_Diff8bitUnFilterVram(); |
|
| 1997 |
- break; |
|
| 1998 |
- case 0x18: |
|
| 1999 |
- {
|
|
| 2000 |
- uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 2001 |
- if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 2002 |
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 2003 |
- SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] + |
|
| 2004 |
- memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 2005 |
- } |
|
| 2006 |
- BIOS_Diff16bitUnFilter(); |
|
| 2007 |
- break; |
|
| 2008 |
- case 0x19: |
|
| 2009 |
-#ifdef GBA_LOGGING |
|
| 2010 |
- if(systemVerbose & VERBOSE_SWI) {
|
|
| 2011 |
- log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n",
|
|
| 2012 |
- reg[0].I, |
|
| 2013 |
- VCOUNT); |
|
| 2014 |
- } |
|
| 2015 |
-#endif |
|
| 2016 |
- if(reg[0].I) |
|
| 2017 |
- soundPause(); |
|
| 2018 |
- else |
|
| 2019 |
- soundResume(); |
|
| 2020 |
- break; |
|
| 2021 |
- case 0x1F: |
|
| 2022 |
- BIOS_MidiKey2Freq(); |
|
| 2023 |
- break; |
|
| 2024 |
- case 0x2A: |
|
| 2025 |
- BIOS_SndDriverJmpTableCopy(); |
|
| 2026 |
- // let it go, because we don't really emulate this function |
|
| 2027 |
- default: |
|
| 2028 |
-#ifdef GBA_LOGGING |
|
| 2029 |
- if(systemVerbose & VERBOSE_SWI) {
|
|
| 2030 |
- log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
|
| 2031 |
- armState ? armNextPC - 4: armNextPC -2, |
|
| 2032 |
- reg[0].I, |
|
| 2033 |
- reg[1].I, |
|
| 2034 |
- reg[2].I, |
|
| 2035 |
- VCOUNT); |
|
| 2036 |
- } |
|
| 2037 |
-#endif |
|
| 2038 |
- |
|
| 2039 |
- if(!disableMessage) {
|
|
| 2040 |
- /*systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION, |
|
| 2041 |
- N_("Unsupported BIOS function %02x called from %08x. A BIOS file is needed in order to get correct behaviour."),
|
|
| 2042 |
- comment, |
|
| 2043 |
- armMode ? armNextPC - 4: armNextPC - 2);*/ |
|
| 2044 |
- disableMessage = true; |
|
| 2045 |
- } |
|
| 2046 |
- break; |
|
| 2047 |
- } |
|
| 497 |
+ if (armState) |
|
| 498 |
+ comment >>= 16; |
|
| 499 |
+ if (comment == 0xfa) |
|
| 500 |
+ return; |
|
| 501 |
+ // This would be correct, but it causes problems if uncommented |
|
| 502 |
+ //else |
|
| 503 |
+ //biosProtected = 0xe3a02004; |
|
| 504 |
+ |
|
| 505 |
+ switch (comment) |
|
| 506 |
+ {
|
|
| 507 |
+ case 0x00: |
|
| 508 |
+ BIOS_SoftReset(); |
|
| 509 |
+ ARM_PREFETCH(); |
|
| 510 |
+ break; |
|
| 511 |
+ case 0x01: |
|
| 512 |
+ BIOS_RegisterRamReset(); |
|
| 513 |
+ break; |
|
| 514 |
+ case 0x02: |
|
| 515 |
+ holdState = true; |
|
| 516 |
+ holdType = -1; |
|
| 517 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 518 |
+ break; |
|
| 519 |
+ case 0x03: |
|
| 520 |
+ break; |
|
| 521 |
+ case 0x04: |
|
| 522 |
+ case 0x05: |
|
| 523 |
+ case 0x06: |
|
| 524 |
+ case 0x07: |
|
| 525 |
+ CPUSoftwareInterrupt(); |
|
| 526 |
+ break; |
|
| 527 |
+ case 0x08: |
|
| 528 |
+ BIOS_Sqrt(); |
|
| 529 |
+ break; |
|
| 530 |
+ case 0x09: |
|
| 531 |
+ BIOS_ArcTan(); |
|
| 532 |
+ break; |
|
| 533 |
+ case 0x0A: |
|
| 534 |
+ BIOS_ArcTan2(); |
|
| 535 |
+ break; |
|
| 536 |
+ case 0x0B: |
|
| 537 |
+ {
|
|
| 538 |
+ int len = (reg[2].I & 0x1FFFFF) >> 1; |
|
| 539 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 540 |
+ {
|
|
| 541 |
+ if ((reg[2].I >> 24) & 1) |
|
| 542 |
+ {
|
|
| 543 |
+ if ((reg[2].I >> 26) & 1) |
|
| 544 |
+ SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); |
|
| 545 |
+ else |
|
| 546 |
+ SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * (len); |
|
| 547 |
+ } |
|
| 548 |
+ else |
|
| 549 |
+ {
|
|
| 550 |
+ if ((reg[2].I >> 26) & 1) |
|
| 551 |
+ SWITicks = (10 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); |
|
| 552 |
+ else |
|
| 553 |
+ SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 554 |
+ } |
|
| 555 |
+ } |
|
| 556 |
+ BIOS_CpuSet(); |
|
| 557 |
+ break; |
|
| 558 |
+ } |
|
| 559 |
+ case 0x0C: |
|
| 560 |
+ {
|
|
| 561 |
+ int len = (reg[2].I & 0x1FFFFF) >> 5; |
|
| 562 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 563 |
+ {
|
|
| 564 |
+ if ((reg[2].I >> 24) & 1) |
|
| 565 |
+ SWITicks = (6 + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 1)) * len; |
|
| 566 |
+ else |
|
| 567 |
+ SWITicks = (9 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[0].I >> 24) & 0xF] + memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 2)) * len; |
|
| 568 |
+ } |
|
| 569 |
+ BIOS_CpuFastSet(); |
|
| 570 |
+ break; |
|
| 571 |
+ } |
|
| 572 |
+ case 0x0D: |
|
| 573 |
+ BIOS_GetBiosChecksum(); |
|
| 574 |
+ break; |
|
| 575 |
+ case 0x0E: |
|
| 576 |
+ BIOS_BgAffineSet(); |
|
| 577 |
+ break; |
|
| 578 |
+ case 0x0F: |
|
| 579 |
+ BIOS_ObjAffineSet(); |
|
| 580 |
+ break; |
|
| 581 |
+ case 0x10: |
|
| 582 |
+ {
|
|
| 583 |
+ int len = CPUReadHalfWord(reg[2].I); |
|
| 584 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + len) & 0xe000000))) |
|
| 585 |
+ SWITicks = (32 + memoryWait[(reg[0].I >> 24) & 0xF]) * len; |
|
| 586 |
+ BIOS_BitUnPack(); |
|
| 587 |
+ break; |
|
| 588 |
+ } |
|
| 589 |
+ case 0x11: |
|
| 590 |
+ {
|
|
| 591 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 592 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 593 |
+ SWITicks = (9 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 594 |
+ BIOS_LZ77UnCompWram(); |
|
| 595 |
+ break; |
|
| 596 |
+ } |
|
| 597 |
+ case 0x12: |
|
| 598 |
+ {
|
|
| 599 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 600 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 601 |
+ SWITicks = (19 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 602 |
+ BIOS_LZ77UnCompVram(); |
|
| 603 |
+ break; |
|
| 604 |
+ } |
|
| 605 |
+ case 0x13: |
|
| 606 |
+ {
|
|
| 607 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 608 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 609 |
+ SWITicks = (29 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1)) * len; |
|
| 610 |
+ BIOS_HuffUnComp(); |
|
| 611 |
+ break; |
|
| 612 |
+ } |
|
| 613 |
+ case 0x14: |
|
| 614 |
+ {
|
|
| 615 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 616 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 617 |
+ SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 618 |
+ BIOS_RLUnCompWram(); |
|
| 619 |
+ break; |
|
| 620 |
+ } |
|
| 621 |
+ case 0x15: |
|
| 622 |
+ {
|
|
| 623 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 624 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 625 |
+ SWITicks = (34 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 626 |
+ BIOS_RLUnCompVram(); |
|
| 627 |
+ break; |
|
| 628 |
+ } |
|
| 629 |
+ case 0x16: |
|
| 630 |
+ {
|
|
| 631 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 632 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 633 |
+ SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 634 |
+ BIOS_Diff8bitUnFilterWram(); |
|
| 635 |
+ break; |
|
| 636 |
+ } |
|
| 637 |
+ case 0x17: |
|
| 638 |
+ {
|
|
| 639 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 640 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 641 |
+ SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF]<<1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 642 |
+ BIOS_Diff8bitUnFilterVram(); |
|
| 643 |
+ break; |
|
| 644 |
+ } |
|
| 645 |
+ case 0x18: |
|
| 646 |
+ {
|
|
| 647 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 648 |
+ if (!(!(reg[0].I & 0xe000000) || !((reg[0].I + (len & 0x1fffff)) & 0xe000000))) |
|
| 649 |
+ SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; |
|
| 650 |
+ BIOS_Diff16bitUnFilter(); |
|
| 651 |
+ break; |
|
| 652 |
+ } |
|
| 653 |
+ case 0x19: |
|
| 654 |
+ if (reg[0].I) |
|
| 655 |
+ soundPause(); |
|
| 656 |
+ else |
|
| 657 |
+ soundResume(); |
|
| 658 |
+ break; |
|
| 659 |
+ case 0x1F: |
|
| 660 |
+ BIOS_MidiKey2Freq(); |
|
| 661 |
+ break; |
|
| 662 |
+ case 0x2A: |
|
| 663 |
+ BIOS_SndDriverJmpTableCopy(); |
|
| 664 |
+ // let it go, because we don't really emulate this function |
|
| 665 |
+ } |
|
| 2048 | 666 |
} |
| 2049 | 667 |
|
| 2050 | 668 |
void CPUCompareVCOUNT() |
| 2051 | 669 |
{
|
| 2052 |
- if(VCOUNT == (DISPSTAT >> 8)) {
|
|
| 2053 |
- DISPSTAT |= 4; |
|
| 2054 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 2055 |
- |
|
| 2056 |
- if(DISPSTAT & 0x20) {
|
|
| 2057 |
- IF |= 4; |
|
| 2058 |
- UPDATE_REG(0x202, IF); |
|
| 2059 |
- } |
|
| 2060 |
- } else {
|
|
| 2061 |
- DISPSTAT &= 0xFFFB; |
|
| 2062 |
- UPDATE_REG(0x4, DISPSTAT); |
|
| 2063 |
- } |
|
| 2064 |
- if (layerEnableDelay>0) |
|
| 2065 |
- {
|
|
| 2066 |
- layerEnableDelay--; |
|
| 2067 |
- if (layerEnableDelay==1) |
|
| 2068 |
- layerEnable = layerSettings & DISPCNT; |
|
| 2069 |
- } |
|
| 670 |
+ if (VCOUNT == (DISPSTAT >> 8)) |
|
| 671 |
+ {
|
|
| 672 |
+ DISPSTAT |= 4; |
|
| 673 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 2070 | 674 |
|
| 675 |
+ if (DISPSTAT & 0x20) |
|
| 676 |
+ {
|
|
| 677 |
+ IF |= 4; |
|
| 678 |
+ UPDATE_REG(0x202, IF); |
|
| 679 |
+ } |
|
| 680 |
+ } |
|
| 681 |
+ else |
|
| 682 |
+ {
|
|
| 683 |
+ DISPSTAT &= 0xFFFB; |
|
| 684 |
+ UPDATE_REG(0x4, DISPSTAT); |
|
| 685 |
+ } |
|
| 686 |
+ if (layerEnableDelay > 0) |
|
| 687 |
+ {
|
|
| 688 |
+ --layerEnableDelay; |
|
| 689 |
+ if (layerEnableDelay == 1) |
|
| 690 |
+ layerEnable = layerSettings & DISPCNT; |
|
| 691 |
+ } |
|
| 2071 | 692 |
} |
| 2072 | 693 |
|
| 2073 | 694 |
void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int transfer32) |
| 2074 | 695 |
{
|
| 2075 |
- int sm = s >> 24; |
|
| 2076 |
- int dm = d >> 24; |
|
| 2077 |
- int sw = 0; |
|
| 2078 |
- int dw = 0; |
|
| 2079 |
- int sc = c; |
|
| 2080 |
- |
|
| 2081 |
- cpuDmaCount = c; |
|
| 2082 |
- // This is done to get the correct waitstates. |
|
| 2083 |
- if (sm>15) |
|
| 2084 |
- sm=15; |
|
| 2085 |
- if (dm>15) |
|
| 2086 |
- dm=15; |
|
| 2087 |
- |
|
| 2088 |
- //if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07)) |
|
| 2089 |
- // blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ? true : false); |
|
| 2090 |
- |
|
| 2091 |
- if(transfer32) {
|
|
| 2092 |
- s &= 0xFFFFFFFC; |
|
| 2093 |
- if(s < 0x02000000 && (reg[15].I >> 24)) {
|
|
| 2094 |
- while(c != 0) {
|
|
| 2095 |
- CPUWriteMemory(d, 0); |
|
| 2096 |
- d += di; |
|
| 2097 |
- c--; |
|
| 2098 |
- } |
|
| 2099 |
- } else {
|
|
| 2100 |
- while(c != 0) {
|
|
| 2101 |
- cpuDmaLast = CPUReadMemory(s); |
|
| 2102 |
- CPUWriteMemory(d, cpuDmaLast); |
|
| 2103 |
- d += di; |
|
| 2104 |
- s += si; |
|
| 2105 |
- c--; |
|
| 2106 |
- } |
|
| 2107 |
- } |
|
| 2108 |
- } else {
|
|
| 2109 |
- s &= 0xFFFFFFFE; |
|
| 2110 |
- si = (int)si >> 1; |
|
| 2111 |
- di = (int)di >> 1; |
|
| 2112 |
- if(s < 0x02000000 && (reg[15].I >> 24)) {
|
|
| 2113 |
- while(c != 0) {
|
|
| 2114 |
- CPUWriteHalfWord(d, 0); |
|
| 2115 |
- d += di; |
|
| 2116 |
- c--; |
|
| 2117 |
- } |
|
| 2118 |
- } else {
|
|
| 2119 |
- while(c != 0) {
|
|
| 2120 |
- cpuDmaLast = CPUReadHalfWord(s); |
|
| 2121 |
- CPUWriteHalfWord(d, cpuDmaLast); |
|
| 2122 |
- cpuDmaLast |= (cpuDmaLast<<16); |
|
| 2123 |
- d += di; |
|
| 2124 |
- s += si; |
|
| 2125 |
- c--; |
|
| 2126 |
- } |
|
| 2127 |
- } |
|
| 2128 |
- } |
|
| 2129 |
- |
|
| 2130 |
- cpuDmaCount = 0; |
|
| 2131 |
- |
|
| 2132 |
- int totalTicks = 0; |
|
| 2133 |
- |
|
| 2134 |
- if(transfer32) {
|
|
| 2135 |
- sw =1+memoryWaitSeq32[sm & 15]; |
|
| 2136 |
- dw =1+memoryWaitSeq32[dm & 15]; |
|
| 2137 |
- totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait32[sm & 15] + |
|
| 2138 |
- memoryWaitSeq32[dm & 15]; |
|
| 2139 |
- } |
|
| 2140 |
- else |
|
| 2141 |
- {
|
|
| 2142 |
- sw = 1+memoryWaitSeq[sm & 15]; |
|
| 2143 |
- dw = 1+memoryWaitSeq[dm & 15]; |
|
| 2144 |
- totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait[sm & 15] + |
|
| 2145 |
- memoryWaitSeq[dm & 15]; |
|
| 2146 |
- } |
|
| 2147 |
- |
|
| 2148 |
- cpuDmaTicksToUpdate += totalTicks; |
|
| 696 |
+ int sm = s >> 24; |
|
| 697 |
+ int dm = d >> 24; |
|
| 698 |
+ int sw = 0; |
|
| 699 |
+ int dw = 0; |
|
| 700 |
+ int sc = c; |
|
| 701 |
+ |
|
| 702 |
+ // This is done to get the correct waitstates. |
|
| 703 |
+ if (sm > 15) |
|
| 704 |
+ sm = 15; |
|
| 705 |
+ if (dm > 15) |
|
| 706 |
+ dm = 15; |
|
| 707 |
+ |
|
| 708 |
+ if (transfer32) |
|
| 709 |
+ {
|
|
| 710 |
+ s &= 0xFFFFFFFC; |
|
| 711 |
+ if (s < 0x02000000 && (reg[15].I >> 24)) |
|
| 712 |
+ {
|
|
| 713 |
+ while (c) |
|
| 714 |
+ {
|
|
| 715 |
+ CPUWriteMemory(d, 0); |
|
| 716 |
+ d += di; |
|
| 717 |
+ --c; |
|
| 718 |
+ } |
|
| 719 |
+ } |
|
| 720 |
+ else |
|
| 721 |
+ {
|
|
| 722 |
+ while (c) |
|
| 723 |
+ {
|
|
| 724 |
+ cpuDmaLast = CPUReadMemory(s); |
|
| 725 |
+ CPUWriteMemory(d, cpuDmaLast); |
|
| 726 |
+ d += di; |
|
| 727 |
+ s += si; |
|
| 728 |
+ --c; |
|
| 729 |
+ } |
|
| 730 |
+ } |
|
| 731 |
+ } |
|
| 732 |
+ else |
|
| 733 |
+ {
|
|
| 734 |
+ s &= 0xFFFFFFFE; |
|
| 735 |
+ si = static_cast<int>(si) >> 1; |
|
| 736 |
+ di = static_cast<int>(di) >> 1; |
|
| 737 |
+ if (s < 0x02000000 && (reg[15].I >> 24)) |
|
| 738 |
+ {
|
|
| 739 |
+ while (c) |
|
| 740 |
+ {
|
|
| 741 |
+ CPUWriteHalfWord(d, 0); |
|
| 742 |
+ d += di; |
|
| 743 |
+ --c; |
|
| 744 |
+ } |
|
| 745 |
+ } |
|
| 746 |
+ else |
|
| 747 |
+ {
|
|
| 748 |
+ while (c) |
|
| 749 |
+ {
|
|
| 750 |
+ cpuDmaLast = CPUReadHalfWord(s); |
|
| 751 |
+ CPUWriteHalfWord(d, cpuDmaLast); |
|
| 752 |
+ cpuDmaLast |= cpuDmaLast << 16; |
|
| 753 |
+ d += di; |
|
| 754 |
+ s += si; |
|
| 755 |
+ --c; |
|
| 756 |
+ } |
|
| 757 |
+ } |
|
| 758 |
+ } |
|
| 2149 | 759 |
|
| 760 |
+ int totalTicks = 0; |
|
| 761 |
+ |
|
| 762 |
+ if (transfer32) |
|
| 763 |
+ {
|
|
| 764 |
+ sw = 1 + memoryWaitSeq32[sm & 15]; |
|
| 765 |
+ dw = 1 + memoryWaitSeq32[dm & 15]; |
|
| 766 |
+ totalTicks = (sw + dw) * (sc - 1) + 6 + memoryWait32[sm & 15] + memoryWaitSeq32[dm & 15]; |
|
| 767 |
+ } |
|
| 768 |
+ else |
|
| 769 |
+ {
|
|
| 770 |
+ sw = 1 + memoryWaitSeq[sm & 15]; |
|
| 771 |
+ dw = 1 + memoryWaitSeq[dm & 15]; |
|
| 772 |
+ totalTicks = (sw + dw) * (sc - 1) + 6 + memoryWait[sm & 15] + memoryWaitSeq[dm & 15]; |
|
| 773 |
+ } |
|
| 774 |
+ |
|
| 775 |
+ cpuDmaTicksToUpdate += totalTicks; |
|
| 2150 | 776 |
} |
| 2151 | 777 |
|
| 2152 | 778 |
void CPUCheckDMA(int reason, int dmamask) |
| 2153 | 779 |
{
|
| 2154 |
- // DMA 0 |
|
| 2155 |
- if((DM0CNT_H & 0x8000) && (dmamask & 1)) {
|
|
| 2156 |
- if(((DM0CNT_H >> 12) & 3) == reason) {
|
|
| 2157 |
- uint32_t sourceIncrement = 4; |
|
| 2158 |
- uint32_t destIncrement = 4; |
|
| 2159 |
- switch((DM0CNT_H >> 7) & 3) {
|
|
| 2160 |
- case 0: |
|
| 2161 |
- break; |
|
| 2162 |
- case 1: |
|
| 2163 |
- sourceIncrement = (uint32_t)-4; |
|
| 2164 |
- break; |
|
| 2165 |
- case 2: |
|
| 2166 |
- sourceIncrement = 0; |
|
| 2167 |
- break; |
|
| 2168 |
- } |
|
| 2169 |
- switch((DM0CNT_H >> 5) & 3) {
|
|
| 2170 |
- case 0: |
|
| 2171 |
- break; |
|
| 2172 |
- case 1: |
|
| 2173 |
- destIncrement = (uint32_t)-4; |
|
| 2174 |
- break; |
|
| 2175 |
- case 2: |
|
| 2176 |
- destIncrement = 0; |
|
| 2177 |
- break; |
|
| 2178 |
- } |
|
| 2179 |
-#ifdef GBA_LOGGING |
|
| 2180 |
- if(systemVerbose & VERBOSE_DMA0) {
|
|
| 2181 |
- int count = (DM0CNT_L ? DM0CNT_L : 0x4000) << 1; |
|
| 2182 |
- if(DM0CNT_H & 0x0400) |
|
| 2183 |
- count <<= 1; |
|
| 2184 |
- log("DMA0: s=%08x d=%08x c=%04x count=%08x\n", dma0Source, dma0Dest,
|
|
| 2185 |
- DM0CNT_H, |
|
| 2186 |
- count); |
|
| 2187 |
- } |
|
| 2188 |
-#endif |
|
| 2189 |
- doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, |
|
| 2190 |
- DM0CNT_L ? DM0CNT_L : 0x4000, |
|
| 2191 |
- DM0CNT_H & 0x0400); |
|
| 2192 |
- |
|
| 2193 |
- if(DM0CNT_H & 0x4000) {
|
|
| 2194 |
- IF |= 0x0100; |
|
| 2195 |
- UPDATE_REG(0x202, IF); |
|
| 2196 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2197 |
- } |
|
| 2198 |
- |
|
| 2199 |
- if(((DM0CNT_H >> 5) & 3) == 3) {
|
|
| 2200 |
- dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 2201 |
- } |
|
| 2202 |
- |
|
| 2203 |
- if(!(DM0CNT_H & 0x0200) || (reason == 0)) {
|
|
| 2204 |
- DM0CNT_H &= 0x7FFF; |
|
| 2205 |
- UPDATE_REG(0xBA, DM0CNT_H); |
|
| 2206 |
- } |
|
| 2207 |
- } |
|
| 2208 |
- } |
|
| 2209 |
- |
|
| 2210 |
- // DMA 1 |
|
| 2211 |
- if((DM1CNT_H & 0x8000) && (dmamask & 2)) {
|
|
| 2212 |
- if(((DM1CNT_H >> 12) & 3) == reason) {
|
|
| 2213 |
- uint32_t sourceIncrement = 4; |
|
| 2214 |
- uint32_t destIncrement = 4; |
|
| 2215 |
- switch((DM1CNT_H >> 7) & 3) {
|
|
| 2216 |
- case 0: |
|
| 2217 |
- break; |
|
| 2218 |
- case 1: |
|
| 2219 |
- sourceIncrement = (uint32_t)-4; |
|
| 2220 |
- break; |
|
| 2221 |
- case 2: |
|
| 2222 |
- sourceIncrement = 0; |
|
| 2223 |
- break; |
|
| 2224 |
- } |
|
| 2225 |
- switch((DM1CNT_H >> 5) & 3) {
|
|
| 2226 |
- case 0: |
|
| 2227 |
- break; |
|
| 2228 |
- case 1: |
|
| 2229 |
- destIncrement = (uint32_t)-4; |
|
| 2230 |
- break; |
|
| 2231 |
- case 2: |
|
| 2232 |
- destIncrement = 0; |
|
| 2233 |
- break; |
|
| 2234 |
- } |
|
| 2235 |
- if(reason == 3) {
|
|
| 2236 |
-#ifdef GBA_LOGGING |
|
| 2237 |
- if(systemVerbose & VERBOSE_DMA1) {
|
|
| 2238 |
- log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
|
|
| 2239 |
- DM1CNT_H, |
|
| 2240 |
- 16); |
|
| 2241 |
- } |
|
| 2242 |
-#endif |
|
| 2243 |
- doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, |
|
| 2244 |
- 0x0400); |
|
| 2245 |
- } else {
|
|
| 2246 |
-#ifdef GBA_LOGGING |
|
| 2247 |
- if(systemVerbose & VERBOSE_DMA1) {
|
|
| 2248 |
- int count = (DM1CNT_L ? DM1CNT_L : 0x4000) << 1; |
|
| 2249 |
- if(DM1CNT_H & 0x0400) |
|
| 2250 |
- count <<= 1; |
|
| 2251 |
- log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
|
|
| 2252 |
- DM1CNT_H, |
|
| 2253 |
- count); |
|
| 2254 |
- } |
|
| 2255 |
-#endif |
|
| 2256 |
- doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, |
|
| 2257 |
- DM1CNT_L ? DM1CNT_L : 0x4000, |
|
| 2258 |
- DM1CNT_H & 0x0400); |
|
| 2259 |
- } |
|
| 2260 |
- |
|
| 2261 |
- if(DM1CNT_H & 0x4000) {
|
|
| 2262 |
- IF |= 0x0200; |
|
| 2263 |
- UPDATE_REG(0x202, IF); |
|
| 2264 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2265 |
- } |
|
| 2266 |
- |
|
| 2267 |
- if(((DM1CNT_H >> 5) & 3) == 3) {
|
|
| 2268 |
- dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 2269 |
- } |
|
| 2270 |
- |
|
| 2271 |
- if(!(DM1CNT_H & 0x0200) || (reason == 0)) {
|
|
| 2272 |
- DM1CNT_H &= 0x7FFF; |
|
| 2273 |
- UPDATE_REG(0xC6, DM1CNT_H); |
|
| 2274 |
- } |
|
| 2275 |
- } |
|
| 2276 |
- } |
|
| 2277 |
- |
|
| 2278 |
- // DMA 2 |
|
| 2279 |
- if((DM2CNT_H & 0x8000) && (dmamask & 4)) {
|
|
| 2280 |
- if(((DM2CNT_H >> 12) & 3) == reason) {
|
|
| 2281 |
- uint32_t sourceIncrement = 4; |
|
| 2282 |
- uint32_t destIncrement = 4; |
|
| 2283 |
- switch((DM2CNT_H >> 7) & 3) {
|
|
| 2284 |
- case 0: |
|
| 2285 |
- break; |
|
| 2286 |
- case 1: |
|
| 2287 |
- sourceIncrement = (uint32_t)-4; |
|
| 2288 |
- break; |
|
| 2289 |
- case 2: |
|
| 2290 |
- sourceIncrement = 0; |
|
| 2291 |
- break; |
|
| 2292 |
- } |
|
| 2293 |
- switch((DM2CNT_H >> 5) & 3) {
|
|
| 2294 |
- case 0: |
|
| 2295 |
- break; |
|
| 2296 |
- case 1: |
|
| 2297 |
- destIncrement = (uint32_t)-4; |
|
| 2298 |
- break; |
|
| 2299 |
- case 2: |
|
| 2300 |
- destIncrement = 0; |
|
| 2301 |
- break; |
|
| 2302 |
- } |
|
| 2303 |
- if(reason == 3) {
|
|
| 2304 |
-#ifdef GBA_LOGGING |
|
| 2305 |
- if(systemVerbose & VERBOSE_DMA2) {
|
|
| 2306 |
- int count = (4) << 2; |
|
| 2307 |
- log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
|
|
| 2308 |
- DM2CNT_H, |
|
| 2309 |
- count); |
|
| 2310 |
- } |
|
| 2311 |
-#endif |
|
| 2312 |
- doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, |
|
| 2313 |
- 0x0400); |
|
| 2314 |
- } else {
|
|
| 2315 |
-#ifdef GBA_LOGGING |
|
| 2316 |
- if(systemVerbose & VERBOSE_DMA2) {
|
|
| 2317 |
- int count = (DM2CNT_L ? DM2CNT_L : 0x4000) << 1; |
|
| 2318 |
- if(DM2CNT_H & 0x0400) |
|
| 2319 |
- count <<= 1; |
|
| 2320 |
- log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
|
|
| 2321 |
- DM2CNT_H, |
|
| 2322 |
- count); |
|
| 2323 |
- } |
|
| 2324 |
-#endif |
|
| 2325 |
- doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, |
|
| 2326 |
- DM2CNT_L ? DM2CNT_L : 0x4000, |
|
| 2327 |
- DM2CNT_H & 0x0400); |
|
| 2328 |
- } |
|
| 2329 |
- |
|
| 2330 |
- if(DM2CNT_H & 0x4000) {
|
|
| 2331 |
- IF |= 0x0400; |
|
| 2332 |
- UPDATE_REG(0x202, IF); |
|
| 2333 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2334 |
- } |
|
| 2335 |
- |
|
| 2336 |
- if(((DM2CNT_H >> 5) & 3) == 3) {
|
|
| 2337 |
- dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 2338 |
- } |
|
| 2339 |
- |
|
| 2340 |
- if(!(DM2CNT_H & 0x0200) || (reason == 0)) {
|
|
| 2341 |
- DM2CNT_H &= 0x7FFF; |
|
| 2342 |
- UPDATE_REG(0xD2, DM2CNT_H); |
|
| 2343 |
- } |
|
| 2344 |
- } |
|
| 2345 |
- } |
|
| 2346 |
- |
|
| 2347 |
- // DMA 3 |
|
| 2348 |
- if((DM3CNT_H & 0x8000) && (dmamask & 8)) {
|
|
| 2349 |
- if(((DM3CNT_H >> 12) & 3) == reason) {
|
|
| 2350 |
- uint32_t sourceIncrement = 4; |
|
| 2351 |
- uint32_t destIncrement = 4; |
|
| 2352 |
- switch((DM3CNT_H >> 7) & 3) {
|
|
| 2353 |
- case 0: |
|
| 2354 |
- break; |
|
| 2355 |
- case 1: |
|
| 2356 |
- sourceIncrement = (uint32_t)-4; |
|
| 2357 |
- break; |
|
| 2358 |
- case 2: |
|
| 2359 |
- sourceIncrement = 0; |
|
| 2360 |
- break; |
|
| 2361 |
- } |
|
| 2362 |
- switch((DM3CNT_H >> 5) & 3) {
|
|
| 2363 |
- case 0: |
|
| 2364 |
- break; |
|
| 2365 |
- case 1: |
|
| 2366 |
- destIncrement = (uint32_t)-4; |
|
| 2367 |
- break; |
|
| 2368 |
- case 2: |
|
| 2369 |
- destIncrement = 0; |
|
| 2370 |
- break; |
|
| 2371 |
- } |
|
| 2372 |
-#ifdef GBA_LOGGING |
|
| 2373 |
- if(systemVerbose & VERBOSE_DMA3) {
|
|
| 2374 |
- int count = (DM3CNT_L ? DM3CNT_L : 0x10000) << 1; |
|
| 2375 |
- if(DM3CNT_H & 0x0400) |
|
| 2376 |
- count <<= 1; |
|
| 2377 |
- log("DMA3: s=%08x d=%08x c=%04x count=%08x\n", dma3Source, dma3Dest,
|
|
| 2378 |
- DM3CNT_H, |
|
| 2379 |
- count); |
|
| 2380 |
- } |
|
| 2381 |
-#endif |
|
| 2382 |
- doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, |
|
| 2383 |
- DM3CNT_L ? DM3CNT_L : 0x10000, |
|
| 2384 |
- DM3CNT_H & 0x0400); |
|
| 2385 |
- if(DM3CNT_H & 0x4000) {
|
|
| 2386 |
- IF |= 0x0800; |
|
| 2387 |
- UPDATE_REG(0x202, IF); |
|
| 2388 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2389 |
- } |
|
| 2390 |
- |
|
| 2391 |
- if(((DM3CNT_H >> 5) & 3) == 3) {
|
|
| 2392 |
- dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 2393 |
- } |
|
| 2394 |
- |
|
| 2395 |
- if(!(DM3CNT_H & 0x0200) || (reason == 0)) {
|
|
| 2396 |
- DM3CNT_H &= 0x7FFF; |
|
| 2397 |
- UPDATE_REG(0xDE, DM3CNT_H); |
|
| 2398 |
- } |
|
| 2399 |
- } |
|
| 2400 |
- } |
|
| 780 |
+ // DMA 0 |
|
| 781 |
+ if ((DM0CNT_H & 0x8000) && (dmamask & 1)) |
|
| 782 |
+ {
|
|
| 783 |
+ if (((DM0CNT_H >> 12) & 3) == reason) |
|
| 784 |
+ {
|
|
| 785 |
+ uint32_t sourceIncrement = 4; |
|
| 786 |
+ uint32_t destIncrement = 4; |
|
| 787 |
+ switch ((DM0CNT_H >> 7) & 3) |
|
| 788 |
+ {
|
|
| 789 |
+ case 0: |
|
| 790 |
+ break; |
|
| 791 |
+ case 1: |
|
| 792 |
+ sourceIncrement = static_cast<uint32_t>(-4); |
|
| 793 |
+ break; |
|
| 794 |
+ case 2: |
|
| 795 |
+ sourceIncrement = 0; |
|
| 796 |
+ } |
|
| 797 |
+ switch ((DM0CNT_H >> 5) & 3) |
|
| 798 |
+ {
|
|
| 799 |
+ case 0: |
|
| 800 |
+ break; |
|
| 801 |
+ case 1: |
|
| 802 |
+ destIncrement = static_cast<uint32_t>(-4); |
|
| 803 |
+ break; |
|
| 804 |
+ case 2: |
|
| 805 |
+ destIncrement = 0; |
|
| 806 |
+ } |
|
| 807 |
+ doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, DM0CNT_L ? DM0CNT_L : 0x4000, DM0CNT_H & 0x0400); |
|
| 808 |
+ |
|
| 809 |
+ if (DM0CNT_H & 0x4000) |
|
| 810 |
+ {
|
|
| 811 |
+ IF |= 0x0100; |
|
| 812 |
+ UPDATE_REG(0x202, IF); |
|
| 813 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 814 |
+ } |
|
| 815 |
+ |
|
| 816 |
+ if (((DM0CNT_H >> 5) & 3) == 3) |
|
| 817 |
+ dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 818 |
+ |
|
| 819 |
+ if (!(DM0CNT_H & 0x0200) || !reason) |
|
| 820 |
+ {
|
|
| 821 |
+ DM0CNT_H &= 0x7FFF; |
|
| 822 |
+ UPDATE_REG(0xBA, DM0CNT_H); |
|
| 823 |
+ } |
|
| 824 |
+ } |
|
| 825 |
+ } |
|
| 826 |
+ |
|
| 827 |
+ // DMA 1 |
|
| 828 |
+ if ((DM1CNT_H & 0x8000) && (dmamask & 2)) |
|
| 829 |
+ {
|
|
| 830 |
+ if (((DM1CNT_H >> 12) & 3) == reason) |
|
| 831 |
+ {
|
|
| 832 |
+ uint32_t sourceIncrement = 4; |
|
| 833 |
+ uint32_t destIncrement = 4; |
|
| 834 |
+ switch ((DM1CNT_H >> 7) & 3) |
|
| 835 |
+ {
|
|
| 836 |
+ case 0: |
|
| 837 |
+ break; |
|
| 838 |
+ case 1: |
|
| 839 |
+ sourceIncrement = static_cast<uint32_t>(-4); |
|
| 840 |
+ break; |
|
| 841 |
+ case 2: |
|
| 842 |
+ sourceIncrement = 0; |
|
| 843 |
+ } |
|
| 844 |
+ switch ((DM1CNT_H >> 5) & 3) |
|
| 845 |
+ {
|
|
| 846 |
+ case 0: |
|
| 847 |
+ break; |
|
| 848 |
+ case 1: |
|
| 849 |
+ destIncrement = static_cast<uint32_t>(-4); |
|
| 850 |
+ break; |
|
| 851 |
+ case 2: |
|
| 852 |
+ destIncrement = 0; |
|
| 853 |
+ } |
|
| 854 |
+ if (reason == 3) |
|
| 855 |
+ doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, 0x0400); |
|
| 856 |
+ else |
|
| 857 |
+ doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, DM1CNT_L ? DM1CNT_L : 0x4000, DM1CNT_H & 0x0400); |
|
| 858 |
+ |
|
| 859 |
+ if (DM1CNT_H & 0x4000) |
|
| 860 |
+ {
|
|
| 861 |
+ IF |= 0x0200; |
|
| 862 |
+ UPDATE_REG(0x202, IF); |
|
| 863 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 864 |
+ } |
|
| 865 |
+ |
|
| 866 |
+ if (((DM1CNT_H >> 5) & 3) == 3) |
|
| 867 |
+ dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 868 |
+ |
|
| 869 |
+ if (!(DM1CNT_H & 0x0200) || !reason) |
|
| 870 |
+ {
|
|
| 871 |
+ DM1CNT_H &= 0x7FFF; |
|
| 872 |
+ UPDATE_REG(0xC6, DM1CNT_H); |
|
| 873 |
+ } |
|
| 874 |
+ } |
|
| 875 |
+ } |
|
| 876 |
+ |
|
| 877 |
+ // DMA 2 |
|
| 878 |
+ if ((DM2CNT_H & 0x8000) && (dmamask & 4)) |
|
| 879 |
+ {
|
|
| 880 |
+ if (((DM2CNT_H >> 12) & 3) == reason) |
|
| 881 |
+ {
|
|
| 882 |
+ uint32_t sourceIncrement = 4; |
|
| 883 |
+ uint32_t destIncrement = 4; |
|
| 884 |
+ switch ((DM2CNT_H >> 7) & 3) |
|
| 885 |
+ {
|
|
| 886 |
+ case 0: |
|
| 887 |
+ break; |
|
| 888 |
+ case 1: |
|
| 889 |
+ sourceIncrement = static_cast<uint32_t>(-4); |
|
| 890 |
+ break; |
|
| 891 |
+ case 2: |
|
| 892 |
+ sourceIncrement = 0; |
|
| 893 |
+ } |
|
| 894 |
+ switch ((DM2CNT_H >> 5) & 3) |
|
| 895 |
+ {
|
|
| 896 |
+ case 0: |
|
| 897 |
+ break; |
|
| 898 |
+ case 1: |
|
| 899 |
+ destIncrement = static_cast<uint32_t>(-4); |
|
| 900 |
+ break; |
|
| 901 |
+ case 2: |
|
| 902 |
+ destIncrement = 0; |
|
| 903 |
+ } |
|
| 904 |
+ if (reason == 3) |
|
| 905 |
+ doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, 0x0400); |
|
| 906 |
+ else |
|
| 907 |
+ doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, DM2CNT_L ? DM2CNT_L : 0x4000, DM2CNT_H & 0x0400); |
|
| 908 |
+ |
|
| 909 |
+ if (DM2CNT_H & 0x4000) |
|
| 910 |
+ {
|
|
| 911 |
+ IF |= 0x0400; |
|
| 912 |
+ UPDATE_REG(0x202, IF); |
|
| 913 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 914 |
+ } |
|
| 915 |
+ |
|
| 916 |
+ if (((DM2CNT_H >> 5) & 3) == 3) |
|
| 917 |
+ dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 918 |
+ |
|
| 919 |
+ if (!(DM2CNT_H & 0x0200) || !reason) |
|
| 920 |
+ {
|
|
| 921 |
+ DM2CNT_H &= 0x7FFF; |
|
| 922 |
+ UPDATE_REG(0xD2, DM2CNT_H); |
|
| 923 |
+ } |
|
| 924 |
+ } |
|
| 925 |
+ } |
|
| 926 |
+ |
|
| 927 |
+ // DMA 3 |
|
| 928 |
+ if ((DM3CNT_H & 0x8000) && (dmamask & 8)) |
|
| 929 |
+ {
|
|
| 930 |
+ if (((DM3CNT_H >> 12) & 3) == reason) |
|
| 931 |
+ {
|
|
| 932 |
+ uint32_t sourceIncrement = 4; |
|
| 933 |
+ uint32_t destIncrement = 4; |
|
| 934 |
+ switch ((DM3CNT_H >> 7) & 3) |
|
| 935 |
+ {
|
|
| 936 |
+ case 0: |
|
| 937 |
+ break; |
|
| 938 |
+ case 1: |
|
| 939 |
+ sourceIncrement = static_cast<uint32_t>(-4); |
|
| 940 |
+ break; |
|
| 941 |
+ case 2: |
|
| 942 |
+ sourceIncrement = 0; |
|
| 943 |
+ } |
|
| 944 |
+ switch ((DM3CNT_H >> 5) & 3) |
|
| 945 |
+ {
|
|
| 946 |
+ case 0: |
|
| 947 |
+ break; |
|
| 948 |
+ case 1: |
|
| 949 |
+ destIncrement = static_cast<uint32_t>(-4); |
|
| 950 |
+ break; |
|
| 951 |
+ case 2: |
|
| 952 |
+ destIncrement = 0; |
|
| 953 |
+ } |
|
| 954 |
+ doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, DM3CNT_L ? DM3CNT_L : 0x10000, DM3CNT_H & 0x0400); |
|
| 955 |
+ if (DM3CNT_H & 0x4000) |
|
| 956 |
+ {
|
|
| 957 |
+ IF |= 0x0800; |
|
| 958 |
+ UPDATE_REG(0x202, IF); |
|
| 959 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 960 |
+ } |
|
| 961 |
+ |
|
| 962 |
+ if (((DM3CNT_H >> 5) & 3) == 3) |
|
| 963 |
+ dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 964 |
+ |
|
| 965 |
+ if (!(DM3CNT_H & 0x0200) || !reason) |
|
| 966 |
+ {
|
|
| 967 |
+ DM3CNT_H &= 0x7FFF; |
|
| 968 |
+ UPDATE_REG(0xDE, DM3CNT_H); |
|
| 969 |
+ } |
|
| 970 |
+ } |
|
| 971 |
+ } |
|
| 2401 | 972 |
} |
| 2402 | 973 |
|
| 2403 | 974 |
void CPUUpdateRegister(uint32_t address, uint16_t value) |
| 2404 | 975 |
{
|
| 2405 |
- switch(address) |
|
| 2406 |
- {
|
|
| 2407 |
- case 0x00: |
|
| 2408 |
- { // we need to place the following code in { } because we declare & initialize variables in a case statement
|
|
| 2409 |
- if((value & 7) > 5) {
|
|
| 2410 |
- // display modes above 0-5 are prohibited |
|
| 2411 |
- DISPCNT = (value & 7); |
|
| 2412 |
- } |
|
| 2413 |
- bool change = (0 != ((DISPCNT ^ value) & 0x80)); |
|
| 2414 |
- bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00)); |
|
| 2415 |
- uint16_t changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated |
|
| 2416 |
- |
|
| 2417 |
- DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode |
|
| 2418 |
- UPDATE_REG(0x00, DISPCNT); |
|
| 2419 |
- |
|
| 2420 |
- if(changeBGon) {
|
|
| 2421 |
- layerEnableDelay = 4; |
|
| 2422 |
- layerEnable = layerSettings & value & (~changeBGon); |
|
| 2423 |
- } else {
|
|
| 2424 |
- layerEnable = layerSettings & value; |
|
| 2425 |
- // CPUUpdateTicks(); |
|
| 2426 |
- } |
|
| 2427 |
- |
|
| 2428 |
- windowOn = (layerEnable & 0x6000) ? true : false; |
|
| 2429 |
- if(change && !((value & 0x80))) {
|
|
| 2430 |
- if(!(DISPSTAT & 1)) {
|
|
| 2431 |
- lcdTicks = 1008; |
|
| 2432 |
- // VCOUNT = 0; |
|
| 2433 |
- // UPDATE_REG(0x06, VCOUNT); |
|
| 2434 |
- DISPSTAT &= 0xFFFC; |
|
| 2435 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 2436 |
- CPUCompareVCOUNT(); |
|
| 2437 |
- } |
|
| 2438 |
- // (*renderLine)(); |
|
| 2439 |
- } |
|
| 2440 |
- //CPUUpdateRender(); |
|
| 2441 |
- // we only care about changes in BG0-BG3 |
|
| 2442 |
- if(changeBG) {
|
|
| 2443 |
- //CPUUpdateRenderBuffers(false); |
|
| 2444 |
- } |
|
| 2445 |
- break; |
|
| 2446 |
- } |
|
| 2447 |
- case 0x04: |
|
| 2448 |
- DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7); |
|
| 2449 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 2450 |
- break; |
|
| 2451 |
- case 0x06: |
|
| 2452 |
- // not writable |
|
| 2453 |
- break; |
|
| 2454 |
- case 0x08: |
|
| 2455 |
- BG0CNT = (value & 0xDFCF); |
|
| 2456 |
- UPDATE_REG(0x08, BG0CNT); |
|
| 2457 |
- break; |
|
| 2458 |
- case 0x0A: |
|
| 2459 |
- BG1CNT = (value & 0xDFCF); |
|
| 2460 |
- UPDATE_REG(0x0A, BG1CNT); |
|
| 2461 |
- break; |
|
| 2462 |
- case 0x0C: |
|
| 2463 |
- BG2CNT = (value & 0xFFCF); |
|
| 2464 |
- UPDATE_REG(0x0C, BG2CNT); |
|
| 2465 |
- break; |
|
| 2466 |
- case 0x0E: |
|
| 2467 |
- BG3CNT = (value & 0xFFCF); |
|
| 2468 |
- UPDATE_REG(0x0E, BG3CNT); |
|
| 2469 |
- break; |
|
| 2470 |
- case 0x10: |
|
| 2471 |
- BG0HOFS = value & 511; |
|
| 2472 |
- UPDATE_REG(0x10, BG0HOFS); |
|
| 2473 |
- break; |
|
| 2474 |
- case 0x12: |
|
| 2475 |
- BG0VOFS = value & 511; |
|
| 2476 |
- UPDATE_REG(0x12, BG0VOFS); |
|
| 2477 |
- break; |
|
| 2478 |
- case 0x14: |
|
| 2479 |
- BG1HOFS = value & 511; |
|
| 2480 |
- UPDATE_REG(0x14, BG1HOFS); |
|
| 2481 |
- break; |
|
| 2482 |
- case 0x16: |
|
| 2483 |
- BG1VOFS = value & 511; |
|
| 2484 |
- UPDATE_REG(0x16, BG1VOFS); |
|
| 2485 |
- break; |
|
| 2486 |
- case 0x18: |
|
| 2487 |
- BG2HOFS = value & 511; |
|
| 2488 |
- UPDATE_REG(0x18, BG2HOFS); |
|
| 2489 |
- break; |
|
| 2490 |
- case 0x1A: |
|
| 2491 |
- BG2VOFS = value & 511; |
|
| 2492 |
- UPDATE_REG(0x1A, BG2VOFS); |
|
| 2493 |
- break; |
|
| 2494 |
- case 0x1C: |
|
| 2495 |
- BG3HOFS = value & 511; |
|
| 2496 |
- UPDATE_REG(0x1C, BG3HOFS); |
|
| 2497 |
- break; |
|
| 2498 |
- case 0x1E: |
|
| 2499 |
- BG3VOFS = value & 511; |
|
| 2500 |
- UPDATE_REG(0x1E, BG3VOFS); |
|
| 2501 |
- break; |
|
| 2502 |
- case 0x20: |
|
| 2503 |
- BG2PA = value; |
|
| 2504 |
- UPDATE_REG(0x20, BG2PA); |
|
| 2505 |
- break; |
|
| 2506 |
- case 0x22: |
|
| 2507 |
- BG2PB = value; |
|
| 2508 |
- UPDATE_REG(0x22, BG2PB); |
|
| 2509 |
- break; |
|
| 2510 |
- case 0x24: |
|
| 2511 |
- BG2PC = value; |
|
| 2512 |
- UPDATE_REG(0x24, BG2PC); |
|
| 2513 |
- break; |
|
| 2514 |
- case 0x26: |
|
| 2515 |
- BG2PD = value; |
|
| 2516 |
- UPDATE_REG(0x26, BG2PD); |
|
| 2517 |
- break; |
|
| 2518 |
- case 0x28: |
|
| 2519 |
- BG2X_L = value; |
|
| 2520 |
- UPDATE_REG(0x28, BG2X_L); |
|
| 2521 |
- //gfxBG2Changed |= 1; |
|
| 2522 |
- break; |
|
| 2523 |
- case 0x2A: |
|
| 2524 |
- BG2X_H = (value & 0xFFF); |
|
| 2525 |
- UPDATE_REG(0x2A, BG2X_H); |
|
| 2526 |
- //gfxBG2Changed |= 1; |
|
| 2527 |
- break; |
|
| 2528 |
- case 0x2C: |
|
| 2529 |
- BG2Y_L = value; |
|
| 2530 |
- UPDATE_REG(0x2C, BG2Y_L); |
|
| 2531 |
- //gfxBG2Changed |= 2; |
|
| 2532 |
- break; |
|
| 2533 |
- case 0x2E: |
|
| 2534 |
- BG2Y_H = value & 0xFFF; |
|
| 2535 |
- UPDATE_REG(0x2E, BG2Y_H); |
|
| 2536 |
- //gfxBG2Changed |= 2; |
|
| 2537 |
- break; |
|
| 2538 |
- case 0x30: |
|
| 2539 |
- BG3PA = value; |
|
| 2540 |
- UPDATE_REG(0x30, BG3PA); |
|
| 2541 |
- break; |
|
| 2542 |
- case 0x32: |
|
| 2543 |
- BG3PB = value; |
|
| 2544 |
- UPDATE_REG(0x32, BG3PB); |
|
| 2545 |
- break; |
|
| 2546 |
- case 0x34: |
|
| 2547 |
- BG3PC = value; |
|
| 2548 |
- UPDATE_REG(0x34, BG3PC); |
|
| 2549 |
- break; |
|
| 2550 |
- case 0x36: |
|
| 2551 |
- BG3PD = value; |
|
| 2552 |
- UPDATE_REG(0x36, BG3PD); |
|
| 2553 |
- break; |
|
| 2554 |
- case 0x38: |
|
| 2555 |
- BG3X_L = value; |
|
| 2556 |
- UPDATE_REG(0x38, BG3X_L); |
|
| 2557 |
- //gfxBG3Changed |= 1; |
|
| 2558 |
- break; |
|
| 2559 |
- case 0x3A: |
|
| 2560 |
- BG3X_H = value & 0xFFF; |
|
| 2561 |
- UPDATE_REG(0x3A, BG3X_H); |
|
| 2562 |
- //gfxBG3Changed |= 1; |
|
| 2563 |
- break; |
|
| 2564 |
- case 0x3C: |
|
| 2565 |
- BG3Y_L = value; |
|
| 2566 |
- UPDATE_REG(0x3C, BG3Y_L); |
|
| 2567 |
- //gfxBG3Changed |= 2; |
|
| 2568 |
- break; |
|
| 2569 |
- case 0x3E: |
|
| 2570 |
- BG3Y_H = value & 0xFFF; |
|
| 2571 |
- UPDATE_REG(0x3E, BG3Y_H); |
|
| 2572 |
- //gfxBG3Changed |= 2; |
|
| 2573 |
- break; |
|
| 2574 |
- case 0x40: |
|
| 2575 |
- WIN0H = value; |
|
| 2576 |
- UPDATE_REG(0x40, WIN0H); |
|
| 2577 |
- //CPUUpdateWindow0(); |
|
| 2578 |
- break; |
|
| 2579 |
- case 0x42: |
|
| 2580 |
- WIN1H = value; |
|
| 2581 |
- UPDATE_REG(0x42, WIN1H); |
|
| 2582 |
- //CPUUpdateWindow1(); |
|
| 2583 |
- break; |
|
| 2584 |
- case 0x44: |
|
| 2585 |
- WIN0V = value; |
|
| 2586 |
- UPDATE_REG(0x44, WIN0V); |
|
| 2587 |
- break; |
|
| 2588 |
- case 0x46: |
|
| 2589 |
- WIN1V = value; |
|
| 2590 |
- UPDATE_REG(0x46, WIN1V); |
|
| 2591 |
- break; |
|
| 2592 |
- case 0x48: |
|
| 2593 |
- WININ = value & 0x3F3F; |
|
| 2594 |
- UPDATE_REG(0x48, WININ); |
|
| 2595 |
- break; |
|
| 2596 |
- case 0x4A: |
|
| 2597 |
- WINOUT = value & 0x3F3F; |
|
| 2598 |
- UPDATE_REG(0x4A, WINOUT); |
|
| 2599 |
- break; |
|
| 2600 |
- case 0x4C: |
|
| 2601 |
- MOSAIC = value; |
|
| 2602 |
- UPDATE_REG(0x4C, MOSAIC); |
|
| 2603 |
- break; |
|
| 2604 |
- case 0x50: |
|
| 2605 |
- BLDMOD = value & 0x3FFF; |
|
| 2606 |
- UPDATE_REG(0x50, BLDMOD); |
|
| 2607 |
- fxOn = ((BLDMOD>>6)&3) != 0; |
|
| 2608 |
- //CPUUpdateRender(); |
|
| 2609 |
- break; |
|
| 2610 |
- case 0x52: |
|
| 2611 |
- COLEV = value & 0x1F1F; |
|
| 2612 |
- UPDATE_REG(0x52, COLEV); |
|
| 2613 |
- break; |
|
| 2614 |
- case 0x54: |
|
| 2615 |
- COLY = value & 0x1F; |
|
| 2616 |
- UPDATE_REG(0x54, COLY); |
|
| 2617 |
- break; |
|
| 2618 |
- case 0x60: |
|
| 2619 |
- case 0x62: |
|
| 2620 |
- case 0x64: |
|
| 2621 |
- case 0x68: |
|
| 2622 |
- case 0x6c: |
|
| 2623 |
- case 0x70: |
|
| 2624 |
- case 0x72: |
|
| 2625 |
- case 0x74: |
|
| 2626 |
- case 0x78: |
|
| 2627 |
- case 0x7c: |
|
| 2628 |
- case 0x80: |
|
| 2629 |
- case 0x84: |
|
| 2630 |
- soundEvent(address&0xFF, (uint8_t)(value & 0xFF)); |
|
| 2631 |
- soundEvent((address&0xFF)+1, (uint8_t)(value>>8)); |
|
| 2632 |
- break; |
|
| 2633 |
- case 0x82: |
|
| 2634 |
- case 0x88: |
|
| 2635 |
- case 0xa0: |
|
| 2636 |
- case 0xa2: |
|
| 2637 |
- case 0xa4: |
|
| 2638 |
- case 0xa6: |
|
| 2639 |
- case 0x90: |
|
| 2640 |
- case 0x92: |
|
| 2641 |
- case 0x94: |
|
| 2642 |
- case 0x96: |
|
| 2643 |
- case 0x98: |
|
| 2644 |
- case 0x9a: |
|
| 2645 |
- case 0x9c: |
|
| 2646 |
- case 0x9e: |
|
| 2647 |
- soundEvent(address&0xFF, value); |
|
| 2648 |
- break; |
|
| 2649 |
- case 0xB0: |
|
| 2650 |
- DM0SAD_L = value; |
|
| 2651 |
- UPDATE_REG(0xB0, DM0SAD_L); |
|
| 2652 |
- break; |
|
| 2653 |
- case 0xB2: |
|
| 2654 |
- DM0SAD_H = value & 0x07FF; |
|
| 2655 |
- UPDATE_REG(0xB2, DM0SAD_H); |
|
| 2656 |
- break; |
|
| 2657 |
- case 0xB4: |
|
| 2658 |
- DM0DAD_L = value; |
|
| 2659 |
- UPDATE_REG(0xB4, DM0DAD_L); |
|
| 2660 |
- break; |
|
| 2661 |
- case 0xB6: |
|
| 2662 |
- DM0DAD_H = value & 0x07FF; |
|
| 2663 |
- UPDATE_REG(0xB6, DM0DAD_H); |
|
| 2664 |
- break; |
|
| 2665 |
- case 0xB8: |
|
| 2666 |
- DM0CNT_L = value & 0x3FFF; |
|
| 2667 |
- UPDATE_REG(0xB8, 0); |
|
| 2668 |
- break; |
|
| 2669 |
- case 0xBA: |
|
| 2670 |
- {
|
|
| 2671 |
- bool start = ((DM0CNT_H ^ value) & 0x8000) ? true : false; |
|
| 2672 |
- value &= 0xF7E0; |
|
| 2673 |
- |
|
| 2674 |
- DM0CNT_H = value; |
|
| 2675 |
- UPDATE_REG(0xBA, DM0CNT_H); |
|
| 2676 |
- |
|
| 2677 |
- if(start && (value & 0x8000)) {
|
|
| 2678 |
- dma0Source = DM0SAD_L | (DM0SAD_H << 16); |
|
| 2679 |
- dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 2680 |
- CPUCheckDMA(0, 1); |
|
| 2681 |
- } |
|
| 2682 |
- } |
|
| 2683 |
- break; |
|
| 2684 |
- case 0xBC: |
|
| 2685 |
- DM1SAD_L = value; |
|
| 2686 |
- UPDATE_REG(0xBC, DM1SAD_L); |
|
| 2687 |
- break; |
|
| 2688 |
- case 0xBE: |
|
| 2689 |
- DM1SAD_H = value & 0x0FFF; |
|
| 2690 |
- UPDATE_REG(0xBE, DM1SAD_H); |
|
| 2691 |
- break; |
|
| 2692 |
- case 0xC0: |
|
| 2693 |
- DM1DAD_L = value; |
|
| 2694 |
- UPDATE_REG(0xC0, DM1DAD_L); |
|
| 2695 |
- break; |
|
| 2696 |
- case 0xC2: |
|
| 2697 |
- DM1DAD_H = value & 0x07FF; |
|
| 2698 |
- UPDATE_REG(0xC2, DM1DAD_H); |
|
| 2699 |
- break; |
|
| 2700 |
- case 0xC4: |
|
| 2701 |
- DM1CNT_L = value & 0x3FFF; |
|
| 2702 |
- UPDATE_REG(0xC4, 0); |
|
| 2703 |
- break; |
|
| 2704 |
- case 0xC6: |
|
| 2705 |
- {
|
|
| 2706 |
- bool start = ((DM1CNT_H ^ value) & 0x8000) ? true : false; |
|
| 2707 |
- value &= 0xF7E0; |
|
| 2708 |
- |
|
| 2709 |
- DM1CNT_H = value; |
|
| 2710 |
- UPDATE_REG(0xC6, DM1CNT_H); |
|
| 2711 |
- |
|
| 2712 |
- if(start && (value & 0x8000)) {
|
|
| 2713 |
- dma1Source = DM1SAD_L | (DM1SAD_H << 16); |
|
| 2714 |
- dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 2715 |
- CPUCheckDMA(0, 2); |
|
| 2716 |
- } |
|
| 2717 |
- } |
|
| 2718 |
- break; |
|
| 2719 |
- case 0xC8: |
|
| 2720 |
- DM2SAD_L = value; |
|
| 2721 |
- UPDATE_REG(0xC8, DM2SAD_L); |
|
| 2722 |
- break; |
|
| 2723 |
- case 0xCA: |
|
| 2724 |
- DM2SAD_H = value & 0x0FFF; |
|
| 2725 |
- UPDATE_REG(0xCA, DM2SAD_H); |
|
| 2726 |
- break; |
|
| 2727 |
- case 0xCC: |
|
| 2728 |
- DM2DAD_L = value; |
|
| 2729 |
- UPDATE_REG(0xCC, DM2DAD_L); |
|
| 2730 |
- break; |
|
| 2731 |
- case 0xCE: |
|
| 2732 |
- DM2DAD_H = value & 0x07FF; |
|
| 2733 |
- UPDATE_REG(0xCE, DM2DAD_H); |
|
| 2734 |
- break; |
|
| 2735 |
- case 0xD0: |
|
| 2736 |
- DM2CNT_L = value & 0x3FFF; |
|
| 2737 |
- UPDATE_REG(0xD0, 0); |
|
| 2738 |
- break; |
|
| 2739 |
- case 0xD2: |
|
| 2740 |
- {
|
|
| 2741 |
- bool start = ((DM2CNT_H ^ value) & 0x8000) ? true : false; |
|
| 2742 |
- |
|
| 2743 |
- value &= 0xF7E0; |
|
| 2744 |
- |
|
| 2745 |
- DM2CNT_H = value; |
|
| 2746 |
- UPDATE_REG(0xD2, DM2CNT_H); |
|
| 2747 |
- |
|
| 2748 |
- if(start && (value & 0x8000)) {
|
|
| 2749 |
- dma2Source = DM2SAD_L | (DM2SAD_H << 16); |
|
| 2750 |
- dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 2751 |
- |
|
| 2752 |
- CPUCheckDMA(0, 4); |
|
| 2753 |
- } |
|
| 2754 |
- } |
|
| 2755 |
- break; |
|
| 2756 |
- case 0xD4: |
|
| 2757 |
- DM3SAD_L = value; |
|
| 2758 |
- UPDATE_REG(0xD4, DM3SAD_L); |
|
| 2759 |
- break; |
|
| 2760 |
- case 0xD6: |
|
| 2761 |
- DM3SAD_H = value & 0x0FFF; |
|
| 2762 |
- UPDATE_REG(0xD6, DM3SAD_H); |
|
| 2763 |
- break; |
|
| 2764 |
- case 0xD8: |
|
| 2765 |
- DM3DAD_L = value; |
|
| 2766 |
- UPDATE_REG(0xD8, DM3DAD_L); |
|
| 2767 |
- break; |
|
| 2768 |
- case 0xDA: |
|
| 2769 |
- DM3DAD_H = value & 0x0FFF; |
|
| 2770 |
- UPDATE_REG(0xDA, DM3DAD_H); |
|
| 2771 |
- break; |
|
| 2772 |
- case 0xDC: |
|
| 2773 |
- DM3CNT_L = value; |
|
| 2774 |
- UPDATE_REG(0xDC, 0); |
|
| 2775 |
- break; |
|
| 2776 |
- case 0xDE: |
|
| 2777 |
- {
|
|
| 2778 |
- bool start = ((DM3CNT_H ^ value) & 0x8000) ? true : false; |
|
| 2779 |
- |
|
| 2780 |
- value &= 0xFFE0; |
|
| 2781 |
- |
|
| 2782 |
- DM3CNT_H = value; |
|
| 2783 |
- UPDATE_REG(0xDE, DM3CNT_H); |
|
| 2784 |
- |
|
| 2785 |
- if(start && (value & 0x8000)) {
|
|
| 2786 |
- dma3Source = DM3SAD_L | (DM3SAD_H << 16); |
|
| 2787 |
- dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 2788 |
- CPUCheckDMA(0,8); |
|
| 2789 |
- } |
|
| 2790 |
- } |
|
| 2791 |
- break; |
|
| 2792 |
- case 0x100: |
|
| 2793 |
- timer0Reload = value; |
|
| 2794 |
- interp_rate(); |
|
| 2795 |
- break; |
|
| 2796 |
- case 0x102: |
|
| 2797 |
- timer0Value = value; |
|
| 2798 |
- timerOnOffDelay|=1; |
|
| 2799 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2800 |
- break; |
|
| 2801 |
- case 0x104: |
|
| 2802 |
- timer1Reload = value; |
|
| 2803 |
- interp_rate(); |
|
| 2804 |
- break; |
|
| 2805 |
- case 0x106: |
|
| 2806 |
- timer1Value = value; |
|
| 2807 |
- timerOnOffDelay|=2; |
|
| 2808 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2809 |
- break; |
|
| 2810 |
- case 0x108: |
|
| 2811 |
- timer2Reload = value; |
|
| 2812 |
- break; |
|
| 2813 |
- case 0x10A: |
|
| 2814 |
- timer2Value = value; |
|
| 2815 |
- timerOnOffDelay|=4; |
|
| 2816 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2817 |
- break; |
|
| 2818 |
- case 0x10C: |
|
| 2819 |
- timer3Reload = value; |
|
| 2820 |
- break; |
|
| 2821 |
- case 0x10E: |
|
| 2822 |
- timer3Value = value; |
|
| 2823 |
- timerOnOffDelay|=8; |
|
| 2824 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2825 |
- break; |
|
| 2826 |
- |
|
| 2827 |
- |
|
| 2828 |
- /*case COMM_SIOCNT: |
|
| 2829 |
- StartLink(value); |
|
| 2830 |
- break; |
|
| 2831 |
- |
|
| 2832 |
- case COMM_SIODATA8: |
|
| 2833 |
- if (gba_link_enabled) |
|
| 2834 |
- LinkSSend(value); |
|
| 2835 |
- UPDATE_REG(COMM_SIODATA8, value); |
|
| 2836 |
- break;*/ |
|
| 2837 |
- |
|
| 2838 |
- case 0x130: |
|
| 2839 |
- P1 |= (value & 0x3FF); |
|
| 2840 |
- UPDATE_REG(0x130, P1); |
|
| 2841 |
- break; |
|
| 2842 |
- |
|
| 2843 |
- case 0x132: |
|
| 2844 |
- UPDATE_REG(0x132, value & 0xC3FF); |
|
| 2845 |
- break; |
|
| 2846 |
- |
|
| 2847 |
- /*case COMM_RCNT: |
|
| 2848 |
- StartGPLink(value); |
|
| 2849 |
- break; |
|
| 2850 |
- |
|
| 2851 |
- case COMM_JOYCNT: |
|
| 2852 |
- {
|
|
| 2853 |
- u16 cur = READ16LE(&ioMem[COMM_JOYCNT]); |
|
| 2854 |
- |
|
| 2855 |
- if (value & JOYCNT_RESET) cur &= ~JOYCNT_RESET; |
|
| 2856 |
- if (value & JOYCNT_RECV_COMPLETE) cur &= ~JOYCNT_RECV_COMPLETE; |
|
| 2857 |
- if (value & JOYCNT_SEND_COMPLETE) cur &= ~JOYCNT_SEND_COMPLETE; |
|
| 2858 |
- if (value & JOYCNT_INT_ENABLE) cur |= JOYCNT_INT_ENABLE; |
|
| 2859 |
- |
|
| 2860 |
- UPDATE_REG(COMM_JOYCNT, cur); |
|
| 2861 |
- } |
|
| 2862 |
- break; |
|
| 2863 |
- |
|
| 2864 |
- case COMM_JOY_RECV_L: |
|
| 2865 |
- UPDATE_REG(COMM_JOY_RECV_L, value); |
|
| 2866 |
- break; |
|
| 2867 |
- case COMM_JOY_RECV_H: |
|
| 2868 |
- UPDATE_REG(COMM_JOY_RECV_H, value); |
|
| 2869 |
- break; |
|
| 2870 |
- |
|
| 2871 |
- case COMM_JOY_TRANS_L: |
|
| 2872 |
- UPDATE_REG(COMM_JOY_TRANS_L, value); |
|
| 2873 |
- UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND); |
|
| 2874 |
- break; |
|
| 2875 |
- case COMM_JOY_TRANS_H: |
|
| 2876 |
- UPDATE_REG(COMM_JOY_TRANS_H, value); |
|
| 2877 |
- break; |
|
| 2878 |
- |
|
| 2879 |
- case COMM_JOYSTAT: |
|
| 2880 |
- UPDATE_REG(COMM_JOYSTAT, (READ16LE(&ioMem[COMM_JOYSTAT]) & 0xf) | (value & 0xf0)); |
|
| 2881 |
- break;*/ |
|
| 2882 |
- |
|
| 2883 |
- case 0x200: |
|
| 2884 |
- IE = value & 0x3FFF; |
|
| 2885 |
- UPDATE_REG(0x200, IE); |
|
| 2886 |
- if ((IME & 1) && (IF & IE) && armIrqEnable) |
|
| 2887 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2888 |
- break; |
|
| 2889 |
- case 0x202: |
|
| 2890 |
- IF ^= (value & IF); |
|
| 2891 |
- UPDATE_REG(0x202, IF); |
|
| 2892 |
- break; |
|
| 2893 |
- case 0x204: |
|
| 2894 |
- {
|
|
| 2895 |
- memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3]; |
|
| 2896 |
- |
|
| 2897 |
- if(!speedHack) {
|
|
| 2898 |
- memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3]; |
|
| 2899 |
- memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = |
|
| 2900 |
- gamepakWaitState0[(value >> 4) & 1]; |
|
| 2901 |
- |
|
| 2902 |
- memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3]; |
|
| 2903 |
- memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = |
|
| 2904 |
- gamepakWaitState1[(value >> 7) & 1]; |
|
| 2905 |
- |
|
| 2906 |
- memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3]; |
|
| 2907 |
- memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = |
|
| 2908 |
- gamepakWaitState2[(value >> 10) & 1]; |
|
| 2909 |
- } else {
|
|
| 2910 |
- memoryWait[0x08] = memoryWait[0x09] = 3; |
|
| 2911 |
- memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = 1; |
|
| 2912 |
- |
|
| 2913 |
- memoryWait[0x0a] = memoryWait[0x0b] = 3; |
|
| 2914 |
- memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = 1; |
|
| 2915 |
- |
|
| 2916 |
- memoryWait[0x0c] = memoryWait[0x0d] = 3; |
|
| 2917 |
- memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = 1; |
|
| 2918 |
- } |
|
| 2919 |
- |
|
| 2920 |
- for(int i = 8; i < 15; i++) {
|
|
| 2921 |
- memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1; |
|
| 2922 |
- memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1; |
|
| 2923 |
- } |
|
| 2924 |
- |
|
| 2925 |
- if((value & 0x4000) == 0x4000) {
|
|
| 2926 |
- busPrefetchEnable = true; |
|
| 2927 |
- busPrefetch = false; |
|
| 2928 |
- busPrefetchCount = 0; |
|
| 2929 |
- } else {
|
|
| 2930 |
- busPrefetchEnable = false; |
|
| 2931 |
- busPrefetch = false; |
|
| 2932 |
- busPrefetchCount = 0; |
|
| 2933 |
- } |
|
| 2934 |
- UPDATE_REG(0x204, value & 0x7FFF); |
|
| 2935 |
- |
|
| 2936 |
- } |
|
| 2937 |
- break; |
|
| 2938 |
- case 0x208: |
|
| 2939 |
- IME = value & 1; |
|
| 2940 |
- UPDATE_REG(0x208, IME); |
|
| 2941 |
- if ((IME & 1) && (IF & IE) && armIrqEnable) |
|
| 2942 |
- cpuNextEvent = cpuTotalTicks; |
|
| 2943 |
- break; |
|
| 2944 |
- case 0x300: |
|
| 2945 |
- if(value != 0) |
|
| 2946 |
- value &= 0xFFFE; |
|
| 2947 |
- UPDATE_REG(0x300, value); |
|
| 2948 |
- break; |
|
| 2949 |
- default: |
|
| 2950 |
- UPDATE_REG(address&0x3FE, value); |
|
| 2951 |
- break; |
|
| 2952 |
- } |
|
| 976 |
+ switch (address) |
|
| 977 |
+ {
|
|
| 978 |
+ case 0x00: |
|
| 979 |
+ {
|
|
| 980 |
+ if ((value & 7) > 5) |
|
| 981 |
+ // display modes above 0-5 are prohibited |
|
| 982 |
+ DISPCNT = value & 7; |
|
| 983 |
+ bool change = !!((DISPCNT ^ value) & 0x80); |
|
| 984 |
+ uint16_t changeBGon = (~DISPCNT & value) & 0x0F00; // these layers are being activated |
|
| 985 |
+ |
|
| 986 |
+ DISPCNT = value & 0xFFF7; // bit 3 can only be accessed by the BIOS to enable GBC mode |
|
| 987 |
+ UPDATE_REG(0x00, DISPCNT); |
|
| 988 |
+ |
|
| 989 |
+ if (changeBGon) |
|
| 990 |
+ {
|
|
| 991 |
+ layerEnableDelay = 4; |
|
| 992 |
+ layerEnable = layerSettings & value & ~changeBGon; |
|
| 993 |
+ } |
|
| 994 |
+ else |
|
| 995 |
+ {
|
|
| 996 |
+ layerEnable = layerSettings & value; |
|
| 997 |
+ //CPUUpdateTicks(); |
|
| 998 |
+ } |
|
| 999 |
+ |
|
| 1000 |
+ if (change && !(value & 0x80)) |
|
| 1001 |
+ {
|
|
| 1002 |
+ if (!(DISPSTAT & 1)) |
|
| 1003 |
+ {
|
|
| 1004 |
+ lcdTicks = 1008; |
|
| 1005 |
+ DISPSTAT &= 0xFFFC; |
|
| 1006 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 1007 |
+ CPUCompareVCOUNT(); |
|
| 1008 |
+ } |
|
| 1009 |
+ } |
|
| 1010 |
+ break; |
|
| 1011 |
+ } |
|
| 1012 |
+ case 0x04: |
|
| 1013 |
+ DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7); |
|
| 1014 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 1015 |
+ break; |
|
| 1016 |
+ case 0x06: |
|
| 1017 |
+ // not writable |
|
| 1018 |
+ break; |
|
| 1019 |
+ case 0x08: |
|
| 1020 |
+ BG0CNT = value & 0xDFCF; |
|
| 1021 |
+ UPDATE_REG(0x08, BG0CNT); |
|
| 1022 |
+ break; |
|
| 1023 |
+ case 0x0A: |
|
| 1024 |
+ BG1CNT = value & 0xDFCF; |
|
| 1025 |
+ UPDATE_REG(0x0A, BG1CNT); |
|
| 1026 |
+ break; |
|
| 1027 |
+ case 0x0C: |
|
| 1028 |
+ BG2CNT = value & 0xFFCF; |
|
| 1029 |
+ UPDATE_REG(0x0C, BG2CNT); |
|
| 1030 |
+ break; |
|
| 1031 |
+ case 0x0E: |
|
| 1032 |
+ BG3CNT = value & 0xFFCF; |
|
| 1033 |
+ UPDATE_REG(0x0E, BG3CNT); |
|
| 1034 |
+ break; |
|
| 1035 |
+ case 0x10: |
|
| 1036 |
+ BG0HOFS = value & 511; |
|
| 1037 |
+ UPDATE_REG(0x10, BG0HOFS); |
|
| 1038 |
+ break; |
|
| 1039 |
+ case 0x12: |
|
| 1040 |
+ BG0VOFS = value & 511; |
|
| 1041 |
+ UPDATE_REG(0x12, BG0VOFS); |
|
| 1042 |
+ break; |
|
| 1043 |
+ case 0x14: |
|
| 1044 |
+ BG1HOFS = value & 511; |
|
| 1045 |
+ UPDATE_REG(0x14, BG1HOFS); |
|
| 1046 |
+ break; |
|
| 1047 |
+ case 0x16: |
|
| 1048 |
+ BG1VOFS = value & 511; |
|
| 1049 |
+ UPDATE_REG(0x16, BG1VOFS); |
|
| 1050 |
+ break; |
|
| 1051 |
+ case 0x18: |
|
| 1052 |
+ BG2HOFS = value & 511; |
|
| 1053 |
+ UPDATE_REG(0x18, BG2HOFS); |
|
| 1054 |
+ break; |
|
| 1055 |
+ case 0x1A: |
|
| 1056 |
+ BG2VOFS = value & 511; |
|
| 1057 |
+ UPDATE_REG(0x1A, BG2VOFS); |
|
| 1058 |
+ break; |
|
| 1059 |
+ case 0x1C: |
|
| 1060 |
+ BG3HOFS = value & 511; |
|
| 1061 |
+ UPDATE_REG(0x1C, BG3HOFS); |
|
| 1062 |
+ break; |
|
| 1063 |
+ case 0x1E: |
|
| 1064 |
+ BG3VOFS = value & 511; |
|
| 1065 |
+ UPDATE_REG(0x1E, BG3VOFS); |
|
| 1066 |
+ break; |
|
| 1067 |
+ case 0x20: |
|
| 1068 |
+ BG2PA = value; |
|
| 1069 |
+ UPDATE_REG(0x20, BG2PA); |
|
| 1070 |
+ break; |
|
| 1071 |
+ case 0x22: |
|
| 1072 |
+ BG2PB = value; |
|
| 1073 |
+ UPDATE_REG(0x22, BG2PB); |
|
| 1074 |
+ break; |
|
| 1075 |
+ case 0x24: |
|
| 1076 |
+ BG2PC = value; |
|
| 1077 |
+ UPDATE_REG(0x24, BG2PC); |
|
| 1078 |
+ break; |
|
| 1079 |
+ case 0x26: |
|
| 1080 |
+ BG2PD = value; |
|
| 1081 |
+ UPDATE_REG(0x26, BG2PD); |
|
| 1082 |
+ break; |
|
| 1083 |
+ case 0x28: |
|
| 1084 |
+ BG2X_L = value; |
|
| 1085 |
+ UPDATE_REG(0x28, BG2X_L); |
|
| 1086 |
+ break; |
|
| 1087 |
+ case 0x2A: |
|
| 1088 |
+ BG2X_H = (value & 0xFFF); |
|
| 1089 |
+ UPDATE_REG(0x2A, BG2X_H); |
|
| 1090 |
+ break; |
|
| 1091 |
+ case 0x2C: |
|
| 1092 |
+ BG2Y_L = value; |
|
| 1093 |
+ UPDATE_REG(0x2C, BG2Y_L); |
|
| 1094 |
+ break; |
|
| 1095 |
+ case 0x2E: |
|
| 1096 |
+ BG2Y_H = value & 0xFFF; |
|
| 1097 |
+ UPDATE_REG(0x2E, BG2Y_H); |
|
| 1098 |
+ break; |
|
| 1099 |
+ case 0x30: |
|
| 1100 |
+ BG3PA = value; |
|
| 1101 |
+ UPDATE_REG(0x30, BG3PA); |
|
| 1102 |
+ break; |
|
| 1103 |
+ case 0x32: |
|
| 1104 |
+ BG3PB = value; |
|
| 1105 |
+ UPDATE_REG(0x32, BG3PB); |
|
| 1106 |
+ break; |
|
| 1107 |
+ case 0x34: |
|
| 1108 |
+ BG3PC = value; |
|
| 1109 |
+ UPDATE_REG(0x34, BG3PC); |
|
| 1110 |
+ break; |
|
| 1111 |
+ case 0x36: |
|
| 1112 |
+ BG3PD = value; |
|
| 1113 |
+ UPDATE_REG(0x36, BG3PD); |
|
| 1114 |
+ break; |
|
| 1115 |
+ case 0x38: |
|
| 1116 |
+ BG3X_L = value; |
|
| 1117 |
+ UPDATE_REG(0x38, BG3X_L); |
|
| 1118 |
+ break; |
|
| 1119 |
+ case 0x3A: |
|
| 1120 |
+ BG3X_H = value & 0xFFF; |
|
| 1121 |
+ UPDATE_REG(0x3A, BG3X_H); |
|
| 1122 |
+ break; |
|
| 1123 |
+ case 0x3C: |
|
| 1124 |
+ BG3Y_L = value; |
|
| 1125 |
+ UPDATE_REG(0x3C, BG3Y_L); |
|
| 1126 |
+ break; |
|
| 1127 |
+ case 0x3E: |
|
| 1128 |
+ BG3Y_H = value & 0xFFF; |
|
| 1129 |
+ UPDATE_REG(0x3E, BG3Y_H); |
|
| 1130 |
+ break; |
|
| 1131 |
+ case 0x40: |
|
| 1132 |
+ WIN0H = value; |
|
| 1133 |
+ UPDATE_REG(0x40, WIN0H); |
|
| 1134 |
+ break; |
|
| 1135 |
+ case 0x42: |
|
| 1136 |
+ WIN1H = value; |
|
| 1137 |
+ UPDATE_REG(0x42, WIN1H); |
|
| 1138 |
+ break; |
|
| 1139 |
+ case 0x44: |
|
| 1140 |
+ WIN0V = value; |
|
| 1141 |
+ UPDATE_REG(0x44, WIN0V); |
|
| 1142 |
+ break; |
|
| 1143 |
+ case 0x46: |
|
| 1144 |
+ WIN1V = value; |
|
| 1145 |
+ UPDATE_REG(0x46, WIN1V); |
|
| 1146 |
+ break; |
|
| 1147 |
+ case 0x48: |
|
| 1148 |
+ WININ = value & 0x3F3F; |
|
| 1149 |
+ UPDATE_REG(0x48, WININ); |
|
| 1150 |
+ break; |
|
| 1151 |
+ case 0x4A: |
|
| 1152 |
+ WINOUT = value & 0x3F3F; |
|
| 1153 |
+ UPDATE_REG(0x4A, WINOUT); |
|
| 1154 |
+ break; |
|
| 1155 |
+ case 0x4C: |
|
| 1156 |
+ MOSAIC = value; |
|
| 1157 |
+ UPDATE_REG(0x4C, MOSAIC); |
|
| 1158 |
+ break; |
|
| 1159 |
+ case 0x50: |
|
| 1160 |
+ BLDMOD = value & 0x3FFF; |
|
| 1161 |
+ UPDATE_REG(0x50, BLDMOD); |
|
| 1162 |
+ break; |
|
| 1163 |
+ case 0x52: |
|
| 1164 |
+ COLEV = value & 0x1F1F; |
|
| 1165 |
+ UPDATE_REG(0x52, COLEV); |
|
| 1166 |
+ break; |
|
| 1167 |
+ case 0x54: |
|
| 1168 |
+ COLY = value & 0x1F; |
|
| 1169 |
+ UPDATE_REG(0x54, COLY); |
|
| 1170 |
+ break; |
|
| 1171 |
+ case 0x60: |
|
| 1172 |
+ case 0x62: |
|
| 1173 |
+ case 0x64: |
|
| 1174 |
+ case 0x68: |
|
| 1175 |
+ case 0x6c: |
|
| 1176 |
+ case 0x70: |
|
| 1177 |
+ case 0x72: |
|
| 1178 |
+ case 0x74: |
|
| 1179 |
+ case 0x78: |
|
| 1180 |
+ case 0x7c: |
|
| 1181 |
+ case 0x80: |
|
| 1182 |
+ case 0x84: |
|
| 1183 |
+ soundEvent(address & 0xFF, static_cast<uint8_t>(value & 0xFF)); |
|
| 1184 |
+ soundEvent((address & 0xFF) + 1, static_cast<uint8_t>(value >> 8)); |
|
| 1185 |
+ break; |
|
| 1186 |
+ case 0x82: |
|
| 1187 |
+ case 0x88: |
|
| 1188 |
+ case 0xa0: |
|
| 1189 |
+ case 0xa2: |
|
| 1190 |
+ case 0xa4: |
|
| 1191 |
+ case 0xa6: |
|
| 1192 |
+ case 0x90: |
|
| 1193 |
+ case 0x92: |
|
| 1194 |
+ case 0x94: |
|
| 1195 |
+ case 0x96: |
|
| 1196 |
+ case 0x98: |
|
| 1197 |
+ case 0x9a: |
|
| 1198 |
+ case 0x9c: |
|
| 1199 |
+ case 0x9e: |
|
| 1200 |
+ soundEvent(address & 0xFF, value); |
|
| 1201 |
+ break; |
|
| 1202 |
+ case 0xB0: |
|
| 1203 |
+ DM0SAD_L = value; |
|
| 1204 |
+ UPDATE_REG(0xB0, DM0SAD_L); |
|
| 1205 |
+ break; |
|
| 1206 |
+ case 0xB2: |
|
| 1207 |
+ DM0SAD_H = value & 0x07FF; |
|
| 1208 |
+ UPDATE_REG(0xB2, DM0SAD_H); |
|
| 1209 |
+ break; |
|
| 1210 |
+ case 0xB4: |
|
| 1211 |
+ DM0DAD_L = value; |
|
| 1212 |
+ UPDATE_REG(0xB4, DM0DAD_L); |
|
| 1213 |
+ break; |
|
| 1214 |
+ case 0xB6: |
|
| 1215 |
+ DM0DAD_H = value & 0x07FF; |
|
| 1216 |
+ UPDATE_REG(0xB6, DM0DAD_H); |
|
| 1217 |
+ break; |
|
| 1218 |
+ case 0xB8: |
|
| 1219 |
+ DM0CNT_L = value & 0x3FFF; |
|
| 1220 |
+ UPDATE_REG(0xB8, 0); |
|
| 1221 |
+ break; |
|
| 1222 |
+ case 0xBA: |
|
| 1223 |
+ {
|
|
| 1224 |
+ bool start = !!((DM0CNT_H ^ value) & 0x8000); |
|
| 1225 |
+ value &= 0xF7E0; |
|
| 1226 |
+ |
|
| 1227 |
+ DM0CNT_H = value; |
|
| 1228 |
+ UPDATE_REG(0xBA, DM0CNT_H); |
|
| 1229 |
+ |
|
| 1230 |
+ if (start && (value & 0x8000)) |
|
| 1231 |
+ {
|
|
| 1232 |
+ dma0Source = DM0SAD_L | (DM0SAD_H << 16); |
|
| 1233 |
+ dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 1234 |
+ CPUCheckDMA(0, 1); |
|
| 1235 |
+ } |
|
| 1236 |
+ break; |
|
| 1237 |
+ } |
|
| 1238 |
+ case 0xBC: |
|
| 1239 |
+ DM1SAD_L = value; |
|
| 1240 |
+ UPDATE_REG(0xBC, DM1SAD_L); |
|
| 1241 |
+ break; |
|
| 1242 |
+ case 0xBE: |
|
| 1243 |
+ DM1SAD_H = value & 0x0FFF; |
|
| 1244 |
+ UPDATE_REG(0xBE, DM1SAD_H); |
|
| 1245 |
+ break; |
|
| 1246 |
+ case 0xC0: |
|
| 1247 |
+ DM1DAD_L = value; |
|
| 1248 |
+ UPDATE_REG(0xC0, DM1DAD_L); |
|
| 1249 |
+ break; |
|
| 1250 |
+ case 0xC2: |
|
| 1251 |
+ DM1DAD_H = value & 0x07FF; |
|
| 1252 |
+ UPDATE_REG(0xC2, DM1DAD_H); |
|
| 1253 |
+ break; |
|
| 1254 |
+ case 0xC4: |
|
| 1255 |
+ DM1CNT_L = value & 0x3FFF; |
|
| 1256 |
+ UPDATE_REG(0xC4, 0); |
|
| 1257 |
+ break; |
|
| 1258 |
+ case 0xC6: |
|
| 1259 |
+ {
|
|
| 1260 |
+ bool start = !!((DM1CNT_H ^ value) & 0x8000); |
|
| 1261 |
+ value &= 0xF7E0; |
|
| 1262 |
+ |
|
| 1263 |
+ DM1CNT_H = value; |
|
| 1264 |
+ UPDATE_REG(0xC6, DM1CNT_H); |
|
| 1265 |
+ |
|
| 1266 |
+ if (start && (value & 0x8000)) |
|
| 1267 |
+ {
|
|
| 1268 |
+ dma1Source = DM1SAD_L | (DM1SAD_H << 16); |
|
| 1269 |
+ dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 1270 |
+ CPUCheckDMA(0, 2); |
|
| 1271 |
+ } |
|
| 1272 |
+ break; |
|
| 1273 |
+ } |
|
| 1274 |
+ case 0xC8: |
|
| 1275 |
+ DM2SAD_L = value; |
|
| 1276 |
+ UPDATE_REG(0xC8, DM2SAD_L); |
|
| 1277 |
+ break; |
|
| 1278 |
+ case 0xCA: |
|
| 1279 |
+ DM2SAD_H = value & 0x0FFF; |
|
| 1280 |
+ UPDATE_REG(0xCA, DM2SAD_H); |
|
| 1281 |
+ break; |
|
| 1282 |
+ case 0xCC: |
|
| 1283 |
+ DM2DAD_L = value; |
|
| 1284 |
+ UPDATE_REG(0xCC, DM2DAD_L); |
|
| 1285 |
+ break; |
|
| 1286 |
+ case 0xCE: |
|
| 1287 |
+ DM2DAD_H = value & 0x07FF; |
|
| 1288 |
+ UPDATE_REG(0xCE, DM2DAD_H); |
|
| 1289 |
+ break; |
|
| 1290 |
+ case 0xD0: |
|
| 1291 |
+ DM2CNT_L = value & 0x3FFF; |
|
| 1292 |
+ UPDATE_REG(0xD0, 0); |
|
| 1293 |
+ break; |
|
| 1294 |
+ case 0xD2: |
|
| 1295 |
+ {
|
|
| 1296 |
+ bool start = !!((DM2CNT_H ^ value) & 0x8000); |
|
| 1297 |
+ value &= 0xF7E0; |
|
| 1298 |
+ |
|
| 1299 |
+ DM2CNT_H = value; |
|
| 1300 |
+ UPDATE_REG(0xD2, DM2CNT_H); |
|
| 1301 |
+ |
|
| 1302 |
+ if (start && (value & 0x8000)) |
|
| 1303 |
+ {
|
|
| 1304 |
+ dma2Source = DM2SAD_L | (DM2SAD_H << 16); |
|
| 1305 |
+ dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 1306 |
+ CPUCheckDMA(0, 4); |
|
| 1307 |
+ } |
|
| 1308 |
+ break; |
|
| 1309 |
+ } |
|
| 1310 |
+ case 0xD4: |
|
| 1311 |
+ DM3SAD_L = value; |
|
| 1312 |
+ UPDATE_REG(0xD4, DM3SAD_L); |
|
| 1313 |
+ break; |
|
| 1314 |
+ case 0xD6: |
|
| 1315 |
+ DM3SAD_H = value & 0x0FFF; |
|
| 1316 |
+ UPDATE_REG(0xD6, DM3SAD_H); |
|
| 1317 |
+ break; |
|
| 1318 |
+ case 0xD8: |
|
| 1319 |
+ DM3DAD_L = value; |
|
| 1320 |
+ UPDATE_REG(0xD8, DM3DAD_L); |
|
| 1321 |
+ break; |
|
| 1322 |
+ case 0xDA: |
|
| 1323 |
+ DM3DAD_H = value & 0x0FFF; |
|
| 1324 |
+ UPDATE_REG(0xDA, DM3DAD_H); |
|
| 1325 |
+ break; |
|
| 1326 |
+ case 0xDC: |
|
| 1327 |
+ DM3CNT_L = value; |
|
| 1328 |
+ UPDATE_REG(0xDC, 0); |
|
| 1329 |
+ break; |
|
| 1330 |
+ case 0xDE: |
|
| 1331 |
+ {
|
|
| 1332 |
+ bool start = !!((DM3CNT_H ^ value) & 0x8000); |
|
| 1333 |
+ value &= 0xFFE0; |
|
| 1334 |
+ |
|
| 1335 |
+ DM3CNT_H = value; |
|
| 1336 |
+ UPDATE_REG(0xDE, DM3CNT_H); |
|
| 1337 |
+ |
|
| 1338 |
+ if (start && (value & 0x8000)) |
|
| 1339 |
+ {
|
|
| 1340 |
+ dma3Source = DM3SAD_L | (DM3SAD_H << 16); |
|
| 1341 |
+ dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 1342 |
+ CPUCheckDMA(0, 8); |
|
| 1343 |
+ } |
|
| 1344 |
+ break; |
|
| 1345 |
+ } |
|
| 1346 |
+ case 0x100: |
|
| 1347 |
+ timer0Reload = value; |
|
| 1348 |
+ break; |
|
| 1349 |
+ case 0x102: |
|
| 1350 |
+ timer0Value = value; |
|
| 1351 |
+ timerOnOffDelay |= 1; |
|
| 1352 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1353 |
+ break; |
|
| 1354 |
+ case 0x104: |
|
| 1355 |
+ timer1Reload = value; |
|
| 1356 |
+ break; |
|
| 1357 |
+ case 0x106: |
|
| 1358 |
+ timer1Value = value; |
|
| 1359 |
+ timerOnOffDelay |= 2; |
|
| 1360 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1361 |
+ break; |
|
| 1362 |
+ case 0x108: |
|
| 1363 |
+ timer2Reload = value; |
|
| 1364 |
+ break; |
|
| 1365 |
+ case 0x10A: |
|
| 1366 |
+ timer2Value = value; |
|
| 1367 |
+ timerOnOffDelay |= 4; |
|
| 1368 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1369 |
+ break; |
|
| 1370 |
+ case 0x10C: |
|
| 1371 |
+ timer3Reload = value; |
|
| 1372 |
+ break; |
|
| 1373 |
+ case 0x10E: |
|
| 1374 |
+ timer3Value = value; |
|
| 1375 |
+ timerOnOffDelay |= 8; |
|
| 1376 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1377 |
+ break; |
|
| 1378 |
+ |
|
| 1379 |
+ case 0x130: |
|
| 1380 |
+ P1 |= value & 0x3FF; |
|
| 1381 |
+ UPDATE_REG(0x130, P1); |
|
| 1382 |
+ break; |
|
| 1383 |
+ |
|
| 1384 |
+ case 0x132: |
|
| 1385 |
+ UPDATE_REG(0x132, value & 0xC3FF); |
|
| 1386 |
+ break; |
|
| 1387 |
+ |
|
| 1388 |
+ case 0x200: |
|
| 1389 |
+ IE = value & 0x3FFF; |
|
| 1390 |
+ UPDATE_REG(0x200, IE); |
|
| 1391 |
+ if ((IME & 1) && (IF & IE) && armIrqEnable) |
|
| 1392 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1393 |
+ break; |
|
| 1394 |
+ case 0x202: |
|
| 1395 |
+ IF ^= value & IF; |
|
| 1396 |
+ UPDATE_REG(0x202, IF); |
|
| 1397 |
+ break; |
|
| 1398 |
+ case 0x204: |
|
| 1399 |
+ memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3]; |
|
| 1400 |
+ |
|
| 1401 |
+ memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3]; |
|
| 1402 |
+ memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = gamepakWaitState0[(value >> 4) & 1]; |
|
| 1403 |
+ |
|
| 1404 |
+ memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3]; |
|
| 1405 |
+ memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = gamepakWaitState1[(value >> 7) & 1]; |
|
| 1406 |
+ |
|
| 1407 |
+ memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3]; |
|
| 1408 |
+ memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = gamepakWaitState2[(value >> 10) & 1]; |
|
| 1409 |
+ |
|
| 1410 |
+ for (int i = 8; i < 15; ++i) |
|
| 1411 |
+ {
|
|
| 1412 |
+ memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1; |
|
| 1413 |
+ memoryWaitSeq32[i] = memoryWaitSeq[i] * 2 + 1; |
|
| 1414 |
+ } |
|
| 1415 |
+ |
|
| 1416 |
+ busPrefetchEnable = (value & 0x4000) == 0x4000; |
|
| 1417 |
+ busPrefetch = false; |
|
| 1418 |
+ busPrefetchCount = 0; |
|
| 1419 |
+ UPDATE_REG(0x204, value & 0x7FFF); |
|
| 1420 |
+ |
|
| 1421 |
+ break; |
|
| 1422 |
+ case 0x208: |
|
| 1423 |
+ IME = value & 1; |
|
| 1424 |
+ UPDATE_REG(0x208, IME); |
|
| 1425 |
+ if ((IME & 1) && (IF & IE) && armIrqEnable) |
|
| 1426 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1427 |
+ break; |
|
| 1428 |
+ case 0x300: |
|
| 1429 |
+ if (value) |
|
| 1430 |
+ value &= 0xFFFE; |
|
| 1431 |
+ UPDATE_REG(0x300, value); |
|
| 1432 |
+ break; |
|
| 1433 |
+ default: |
|
| 1434 |
+ UPDATE_REG(address & 0x3FE, value); |
|
| 1435 |
+ } |
|
| 2953 | 1436 |
} |
| 2954 | 1437 |
|
| 2955 |
-void applyTimer () |
|
| 1438 |
+void applyTimer() |
|
| 2956 | 1439 |
{
|
| 2957 |
- if (timerOnOffDelay & 1) |
|
| 2958 |
- {
|
|
| 2959 |
- timer0ClockReload = TIMER_TICKS[timer0Value & 3]; |
|
| 2960 |
- if(!timer0On && (timer0Value & 0x80)) {
|
|
| 2961 |
- // reload the counter |
|
| 2962 |
- TM0D = timer0Reload; |
|
| 2963 |
- timer0Ticks = (0x10000 - TM0D) << timer0ClockReload; |
|
| 2964 |
- UPDATE_REG(0x100, TM0D); |
|
| 2965 |
- } |
|
| 2966 |
- timer0On = timer0Value & 0x80 ? true : false; |
|
| 2967 |
- TM0CNT = timer0Value & 0xC7; |
|
| 2968 |
- interp_rate(); |
|
| 2969 |
- UPDATE_REG(0x102, TM0CNT); |
|
| 2970 |
- // CPUUpdateTicks(); |
|
| 2971 |
- } |
|
| 2972 |
- if (timerOnOffDelay & 2) |
|
| 2973 |
- {
|
|
| 2974 |
- timer1ClockReload = TIMER_TICKS[timer1Value & 3]; |
|
| 2975 |
- if(!timer1On && (timer1Value & 0x80)) {
|
|
| 2976 |
- // reload the counter |
|
| 2977 |
- TM1D = timer1Reload; |
|
| 2978 |
- timer1Ticks = (0x10000 - TM1D) << timer1ClockReload; |
|
| 2979 |
- UPDATE_REG(0x104, TM1D); |
|
| 2980 |
- } |
|
| 2981 |
- timer1On = timer1Value & 0x80 ? true : false; |
|
| 2982 |
- TM1CNT = timer1Value & 0xC7; |
|
| 2983 |
- interp_rate(); |
|
| 2984 |
- UPDATE_REG(0x106, TM1CNT); |
|
| 2985 |
- } |
|
| 2986 |
- if (timerOnOffDelay & 4) |
|
| 2987 |
- {
|
|
| 2988 |
- timer2ClockReload = TIMER_TICKS[timer2Value & 3]; |
|
| 2989 |
- if(!timer2On && (timer2Value & 0x80)) {
|
|
| 2990 |
- // reload the counter |
|
| 2991 |
- TM2D = timer2Reload; |
|
| 2992 |
- timer2Ticks = (0x10000 - TM2D) << timer2ClockReload; |
|
| 2993 |
- UPDATE_REG(0x108, TM2D); |
|
| 2994 |
- } |
|
| 2995 |
- timer2On = timer2Value & 0x80 ? true : false; |
|
| 2996 |
- TM2CNT = timer2Value & 0xC7; |
|
| 2997 |
- UPDATE_REG(0x10A, TM2CNT); |
|
| 2998 |
- } |
|
| 2999 |
- if (timerOnOffDelay & 8) |
|
| 3000 |
- {
|
|
| 3001 |
- timer3ClockReload = TIMER_TICKS[timer3Value & 3]; |
|
| 3002 |
- if(!timer3On && (timer3Value & 0x80)) {
|
|
| 3003 |
- // reload the counter |
|
| 3004 |
- TM3D = timer3Reload; |
|
| 3005 |
- timer3Ticks = (0x10000 - TM3D) << timer3ClockReload; |
|
| 3006 |
- UPDATE_REG(0x10C, TM3D); |
|
| 3007 |
- } |
|
| 3008 |
- timer3On = timer3Value & 0x80 ? true : false; |
|
| 3009 |
- TM3CNT = timer3Value & 0xC7; |
|
| 3010 |
- UPDATE_REG(0x10E, TM3CNT); |
|
| 3011 |
- } |
|
| 3012 |
- cpuNextEvent = CPUUpdateTicks(); |
|
| 3013 |
- timerOnOffDelay = 0; |
|
| 1440 |
+ if (timerOnOffDelay & 1) |
|
| 1441 |
+ {
|
|
| 1442 |
+ timer0ClockReload = TIMER_TICKS[timer0Value & 3]; |
|
| 1443 |
+ if (!timer0On && (timer0Value & 0x80)) |
|
| 1444 |
+ {
|
|
| 1445 |
+ // reload the counter |
|
| 1446 |
+ TM0D = timer0Reload; |
|
| 1447 |
+ timer0Ticks = (0x10000 - TM0D) << timer0ClockReload; |
|
| 1448 |
+ UPDATE_REG(0x100, TM0D); |
|
| 1449 |
+ } |
|
| 1450 |
+ timer0On = !!(timer0Value & 0x80); |
|
| 1451 |
+ TM0CNT = timer0Value & 0xC7; |
|
| 1452 |
+ UPDATE_REG(0x102, TM0CNT); |
|
| 1453 |
+ //CPUUpdateTicks(); |
|
| 1454 |
+ } |
|
| 1455 |
+ if (timerOnOffDelay & 2) |
|
| 1456 |
+ {
|
|
| 1457 |
+ timer1ClockReload = TIMER_TICKS[timer1Value & 3]; |
|
| 1458 |
+ if (!timer1On && (timer1Value & 0x80)) |
|
| 1459 |
+ {
|
|
| 1460 |
+ // reload the counter |
|
| 1461 |
+ TM1D = timer1Reload; |
|
| 1462 |
+ timer1Ticks = (0x10000 - TM1D) << timer1ClockReload; |
|
| 1463 |
+ UPDATE_REG(0x104, TM1D); |
|
| 1464 |
+ } |
|
| 1465 |
+ timer1On = !!(timer1Value & 0x80); |
|
| 1466 |
+ TM1CNT = timer1Value & 0xC7; |
|
| 1467 |
+ UPDATE_REG(0x106, TM1CNT); |
|
| 1468 |
+ } |
|
| 1469 |
+ if (timerOnOffDelay & 4) |
|
| 1470 |
+ {
|
|
| 1471 |
+ timer2ClockReload = TIMER_TICKS[timer2Value & 3]; |
|
| 1472 |
+ if (!timer2On && (timer2Value & 0x80)) |
|
| 1473 |
+ {
|
|
| 1474 |
+ // reload the counter |
|
| 1475 |
+ TM2D = timer2Reload; |
|
| 1476 |
+ timer2Ticks = (0x10000 - TM2D) << timer2ClockReload; |
|
| 1477 |
+ UPDATE_REG(0x108, TM2D); |
|
| 1478 |
+ } |
|
| 1479 |
+ timer2On = !(timer2Value & 0x80); |
|
| 1480 |
+ TM2CNT = timer2Value & 0xC7; |
|
| 1481 |
+ UPDATE_REG(0x10A, TM2CNT); |
|
| 1482 |
+ } |
|
| 1483 |
+ if (timerOnOffDelay & 8) |
|
| 1484 |
+ {
|
|
| 1485 |
+ timer3ClockReload = TIMER_TICKS[timer3Value & 3]; |
|
| 1486 |
+ if (!timer3On && (timer3Value & 0x80)) |
|
| 1487 |
+ {
|
|
| 1488 |
+ // reload the counter |
|
| 1489 |
+ TM3D = timer3Reload; |
|
| 1490 |
+ timer3Ticks = (0x10000 - TM3D) << timer3ClockReload; |
|
| 1491 |
+ UPDATE_REG(0x10C, TM3D); |
|
| 1492 |
+ } |
|
| 1493 |
+ timer3On = !!(timer3Value & 0x80); |
|
| 1494 |
+ TM3CNT = timer3Value & 0xC7; |
|
| 1495 |
+ UPDATE_REG(0x10E, TM3CNT); |
|
| 1496 |
+ } |
|
| 1497 |
+ cpuNextEvent = CPUUpdateTicks(); |
|
| 1498 |
+ timerOnOffDelay = 0; |
|
| 3014 | 1499 |
} |
| 3015 | 1500 |
|
| 3016 | 1501 |
uint8_t cpuBitsSet[256]; |
| 3017 | 1502 |
uint8_t cpuLowestBitSet[256]; |
| 3018 | 1503 |
|
| 3019 |
-void CPUInit(const char *biosFileName, bool useBiosFile) |
|
| 1504 |
+void CPUInit() |
|
| 3020 | 1505 |
{
|
| 3021 | 1506 |
#ifdef WORDS_BIGENDIAN |
| 3022 |
- if(!cpuBiosSwapped) {
|
|
| 3023 |
- for(unsigned int i = 0; i < sizeof(myROM)/4; i++) {
|
|
| 3024 |
- WRITE32LE(&myROM[i], myROM[i]); |
|
| 3025 |
- } |
|
| 3026 |
- cpuBiosSwapped = true; |
|
| 3027 |
- } |
|
| 1507 |
+ if (!cpuBiosSwapped) |
|
| 1508 |
+ {
|
|
| 1509 |
+ for (unsigned i = 0; i < sizeof(myROM) / 4; ++i) |
|
| 1510 |
+ WRITE32LE(&myROM[i], myROM[i]); |
|
| 1511 |
+ cpuBiosSwapped = true; |
|
| 1512 |
+ } |
|
| 3028 | 1513 |
#endif |
| 3029 |
- gbaSaveType = 0; |
|
| 3030 |
- //eepromInUse = 0; |
|
| 3031 |
- saveType = 0; |
|
| 3032 |
- useBios = false; |
|
| 3033 |
- |
|
| 3034 |
- /*if(useBiosFile) {
|
|
| 3035 |
- int size = 0x4000; |
|
| 3036 |
- if(utilLoad(biosFileName, |
|
| 3037 |
- CPUIsGBABios, |
|
| 3038 |
- bios, |
|
| 3039 |
- size)) {
|
|
| 3040 |
- if(size == 0x4000) |
|
| 3041 |
- useBios = true; |
|
| 3042 |
- else |
|
| 3043 |
- systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BIOS file size"));
|
|
| 3044 |
- } |
|
| 3045 |
- }*/ |
|
| 3046 |
- |
|
| 3047 |
- if(!useBios) {
|
|
| 3048 |
- memcpy(bios, myROM, sizeof(myROM)); |
|
| 3049 |
- } |
|
| 3050 |
- |
|
| 3051 |
- int i = 0; |
|
| 3052 |
- |
|
| 3053 |
- biosProtected[0] = 0x00; |
|
| 3054 |
- biosProtected[1] = 0xf0; |
|
| 3055 |
- biosProtected[2] = 0x29; |
|
| 3056 |
- biosProtected[3] = 0xe1; |
|
| 3057 |
- |
|
| 3058 |
- for(i = 0; i < 256; i++) {
|
|
| 3059 |
- int count = 0; |
|
| 3060 |
- int j; |
|
| 3061 |
- for(j = 0; j < 8; j++) |
|
| 3062 |
- if(i & (1 << j)) |
|
| 3063 |
- count++; |
|
| 3064 |
- cpuBitsSet[i] = count; |
|
| 3065 |
- |
|
| 3066 |
- for(j = 0; j < 8; j++) |
|
| 3067 |
- if(i & (1 << j)) |
|
| 3068 |
- break; |
|
| 3069 |
- cpuLowestBitSet[i] = j; |
|
| 3070 |
- } |
|
| 3071 |
- |
|
| 3072 |
- for(i = 0; i < 0x400; i++) |
|
| 3073 |
- ioReadable[i] = true; |
|
| 3074 |
- for(i = 0x10; i < 0x48; i++) |
|
| 3075 |
- ioReadable[i] = false; |
|
| 3076 |
- for(i = 0x4c; i < 0x50; i++) |
|
| 3077 |
- ioReadable[i] = false; |
|
| 3078 |
- for(i = 0x54; i < 0x60; i++) |
|
| 3079 |
- ioReadable[i] = false; |
|
| 3080 |
- for(i = 0x8c; i < 0x90; i++) |
|
| 3081 |
- ioReadable[i] = false; |
|
| 3082 |
- for(i = 0xa0; i < 0xb8; i++) |
|
| 3083 |
- ioReadable[i] = false; |
|
| 3084 |
- for(i = 0xbc; i < 0xc4; i++) |
|
| 3085 |
- ioReadable[i] = false; |
|
| 3086 |
- for(i = 0xc8; i < 0xd0; i++) |
|
| 3087 |
- ioReadable[i] = false; |
|
| 3088 |
- for(i = 0xd4; i < 0xdc; i++) |
|
| 3089 |
- ioReadable[i] = false; |
|
| 3090 |
- for(i = 0xe0; i < 0x100; i++) |
|
| 3091 |
- ioReadable[i] = false; |
|
| 3092 |
- for(i = 0x110; i < 0x120; i++) |
|
| 3093 |
- ioReadable[i] = false; |
|
| 3094 |
- for(i = 0x12c; i < 0x130; i++) |
|
| 3095 |
- ioReadable[i] = false; |
|
| 3096 |
- for(i = 0x138; i < 0x140; i++) |
|
| 3097 |
- ioReadable[i] = false; |
|
| 3098 |
- for(i = 0x144; i < 0x150; i++) |
|
| 3099 |
- ioReadable[i] = false; |
|
| 3100 |
- for(i = 0x15c; i < 0x200; i++) |
|
| 3101 |
- ioReadable[i] = false; |
|
| 3102 |
- for(i = 0x20c; i < 0x300; i++) |
|
| 3103 |
- ioReadable[i] = false; |
|
| 3104 |
- for(i = 0x304; i < 0x400; i++) |
|
| 3105 |
- ioReadable[i] = false; |
|
| 3106 |
- |
|
| 3107 |
- if(romSize < 0x1fe2000) {
|
|
| 3108 |
- *((uint16_t *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA |
|
| 3109 |
- *((uint16_t *)&rom[0x1fe209e]) = 0x4770; // BX LR |
|
| 3110 |
- } else {
|
|
| 3111 |
- //agbPrintEnable(false); |
|
| 3112 |
- } |
|
| 1514 |
+ memcpy(&bios[0], myROM, sizeof(myROM)); |
|
| 1515 |
+ |
|
| 1516 |
+ biosProtected[0] = 0x00; |
|
| 1517 |
+ biosProtected[1] = 0xf0; |
|
| 1518 |
+ biosProtected[2] = 0x29; |
|
| 1519 |
+ biosProtected[3] = 0xe1; |
|
| 1520 |
+ |
|
| 1521 |
+ for (int i = 0; i < 256; ++i) |
|
| 1522 |
+ {
|
|
| 1523 |
+ int count = 0; |
|
| 1524 |
+ int j; |
|
| 1525 |
+ for (j = 0; j < 8; ++j) |
|
| 1526 |
+ if (i & (1 << j)) |
|
| 1527 |
+ ++count; |
|
| 1528 |
+ cpuBitsSet[i] = count; |
|
| 1529 |
+ |
|
| 1530 |
+ for (j = 0; j < 8; ++j) |
|
| 1531 |
+ if (i & (1 << j)) |
|
| 1532 |
+ break; |
|
| 1533 |
+ cpuLowestBitSet[i] = j; |
|
| 1534 |
+ } |
|
| 1535 |
+ |
|
| 1536 |
+ std::fill(&ioReadable[0], &ioReadable[0x304], true); |
|
| 1537 |
+ std::fill(&ioReadable[0x10], &ioReadable[0x48], false); |
|
| 1538 |
+ std::fill(&ioReadable[0x4c], &ioReadable[0x50], false); |
|
| 1539 |
+ std::fill(&ioReadable[0x54], &ioReadable[0x60], false); |
|
| 1540 |
+ std::fill(&ioReadable[0x8c], &ioReadable[0x90], false); |
|
| 1541 |
+ std::fill(&ioReadable[0xa0], &ioReadable[0xb8], false); |
|
| 1542 |
+ std::fill(&ioReadable[0xbc], &ioReadable[0xc4], false); |
|
| 1543 |
+ std::fill(&ioReadable[0xc8], &ioReadable[0xd0], false); |
|
| 1544 |
+ std::fill(&ioReadable[0xd4], &ioReadable[0xdc], false); |
|
| 1545 |
+ std::fill(&ioReadable[0xe0], &ioReadable[0x100], false); |
|
| 1546 |
+ std::fill(&ioReadable[0x110], &ioReadable[0x120], false); |
|
| 1547 |
+ std::fill(&ioReadable[0x12c], &ioReadable[0x130], false); |
|
| 1548 |
+ std::fill(&ioReadable[0x138], &ioReadable[0x140], false); |
|
| 1549 |
+ std::fill(&ioReadable[0x144], &ioReadable[0x150], false); |
|
| 1550 |
+ std::fill(&ioReadable[0x15c], &ioReadable[0x200], false); |
|
| 1551 |
+ std::fill(&ioReadable[0x20c], &ioReadable[0x300], false); |
|
| 1552 |
+ std::fill(&ioReadable[0x304], &ioReadable[0x400], false); |
|
| 1553 |
+ |
|
| 1554 |
+ if (romSize < 0x1fe2000) |
|
| 1555 |
+ {
|
|
| 1556 |
+ *reinterpret_cast<uint16_t *>(&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA |
|
| 1557 |
+ *reinterpret_cast<uint16_t *>(&rom[0x1fe209e]) = 0x4770; // BX LR |
|
| 1558 |
+ } |
|
| 3113 | 1559 |
} |
| 3114 | 1560 |
|
| 3115 | 1561 |
void CPUReset() |
| 3116 | 1562 |
{
|
| 3117 |
- /*if(gbaSaveType == 0) {
|
|
| 3118 |
- if(eepromInUse) |
|
| 3119 |
- gbaSaveType = 3; |
|
| 3120 |
- else |
|
| 3121 |
- switch(saveType) {
|
|
| 3122 |
- case 1: |
|
| 3123 |
- gbaSaveType = 1; |
|
| 3124 |
- break; |
|
| 3125 |
- case 2: |
|
| 3126 |
- gbaSaveType = 2; |
|
| 3127 |
- break; |
|
| 3128 |
- } |
|
| 3129 |
- } |
|
| 3130 |
- rtcReset();*/ |
|
| 3131 |
- // clean registers |
|
| 3132 |
- memset(®[0], 0, sizeof(reg)); |
|
| 3133 |
- // clean OAM |
|
| 3134 |
- memset(oam, 0, 0x400); |
|
| 3135 |
- // clean palette |
|
| 3136 |
- memset(paletteRAM, 0, 0x400); |
|
| 3137 |
- // clean picture |
|
| 3138 |
- memset(pix, 0, 4*160*240); |
|
| 3139 |
- // clean vram |
|
| 3140 |
- memset(vram, 0, 0x20000); |
|
| 3141 |
- // clean io memory |
|
| 3142 |
- memset(ioMem, 0, 0x400); |
|
| 3143 |
- |
|
| 3144 |
- DISPCNT = 0x0080; |
|
| 3145 |
- DISPSTAT = 0x0000; |
|
| 3146 |
- VCOUNT = (useBios && !skipBios) ? 0 :0x007E; |
|
| 3147 |
- BG0CNT = 0x0000; |
|
| 3148 |
- BG1CNT = 0x0000; |
|
| 3149 |
- BG2CNT = 0x0000; |
|
| 3150 |
- BG3CNT = 0x0000; |
|
| 3151 |
- BG0HOFS = 0x0000; |
|
| 3152 |
- BG0VOFS = 0x0000; |
|
| 3153 |
- BG1HOFS = 0x0000; |
|
| 3154 |
- BG1VOFS = 0x0000; |
|
| 3155 |
- BG2HOFS = 0x0000; |
|
| 3156 |
- BG2VOFS = 0x0000; |
|
| 3157 |
- BG3HOFS = 0x0000; |
|
| 3158 |
- BG3VOFS = 0x0000; |
|
| 3159 |
- BG2PA = 0x0100; |
|
| 3160 |
- BG2PB = 0x0000; |
|
| 3161 |
- BG2PC = 0x0000; |
|
| 3162 |
- BG2PD = 0x0100; |
|
| 3163 |
- BG2X_L = 0x0000; |
|
| 3164 |
- BG2X_H = 0x0000; |
|
| 3165 |
- BG2Y_L = 0x0000; |
|
| 3166 |
- BG2Y_H = 0x0000; |
|
| 3167 |
- BG3PA = 0x0100; |
|
| 3168 |
- BG3PB = 0x0000; |
|
| 3169 |
- BG3PC = 0x0000; |
|
| 3170 |
- BG3PD = 0x0100; |
|
| 3171 |
- BG3X_L = 0x0000; |
|
| 3172 |
- BG3X_H = 0x0000; |
|
| 3173 |
- BG3Y_L = 0x0000; |
|
| 3174 |
- BG3Y_H = 0x0000; |
|
| 3175 |
- WIN0H = 0x0000; |
|
| 3176 |
- WIN1H = 0x0000; |
|
| 3177 |
- WIN0V = 0x0000; |
|
| 3178 |
- WIN1V = 0x0000; |
|
| 3179 |
- WININ = 0x0000; |
|
| 3180 |
- WINOUT = 0x0000; |
|
| 3181 |
- MOSAIC = 0x0000; |
|
| 3182 |
- BLDMOD = 0x0000; |
|
| 3183 |
- COLEV = 0x0000; |
|
| 3184 |
- COLY = 0x0000; |
|
| 3185 |
- DM0SAD_L = 0x0000; |
|
| 3186 |
- DM0SAD_H = 0x0000; |
|
| 3187 |
- DM0DAD_L = 0x0000; |
|
| 3188 |
- DM0DAD_H = 0x0000; |
|
| 3189 |
- DM0CNT_L = 0x0000; |
|
| 3190 |
- DM0CNT_H = 0x0000; |
|
| 3191 |
- DM1SAD_L = 0x0000; |
|
| 3192 |
- DM1SAD_H = 0x0000; |
|
| 3193 |
- DM1DAD_L = 0x0000; |
|
| 3194 |
- DM1DAD_H = 0x0000; |
|
| 3195 |
- DM1CNT_L = 0x0000; |
|
| 3196 |
- DM1CNT_H = 0x0000; |
|
| 3197 |
- DM2SAD_L = 0x0000; |
|
| 3198 |
- DM2SAD_H = 0x0000; |
|
| 3199 |
- DM2DAD_L = 0x0000; |
|
| 3200 |
- DM2DAD_H = 0x0000; |
|
| 3201 |
- DM2CNT_L = 0x0000; |
|
| 3202 |
- DM2CNT_H = 0x0000; |
|
| 3203 |
- DM3SAD_L = 0x0000; |
|
| 3204 |
- DM3SAD_H = 0x0000; |
|
| 3205 |
- DM3DAD_L = 0x0000; |
|
| 3206 |
- DM3DAD_H = 0x0000; |
|
| 3207 |
- DM3CNT_L = 0x0000; |
|
| 3208 |
- DM3CNT_H = 0x0000; |
|
| 3209 |
- TM0D = 0x0000; |
|
| 3210 |
- TM0CNT = 0x0000; |
|
| 3211 |
- TM1D = 0x0000; |
|
| 3212 |
- TM1CNT = 0x0000; |
|
| 3213 |
- TM2D = 0x0000; |
|
| 3214 |
- TM2CNT = 0x0000; |
|
| 3215 |
- TM3D = 0x0000; |
|
| 3216 |
- TM3CNT = 0x0000; |
|
| 3217 |
- P1 = 0x03FF; |
|
| 3218 |
- IE = 0x0000; |
|
| 3219 |
- IF = 0x0000; |
|
| 3220 |
- IME = 0x0000; |
|
| 3221 |
- |
|
| 3222 |
- armMode = 0x1F; |
|
| 3223 |
- |
|
| 3224 |
- if(cpuIsMultiBoot) {
|
|
| 3225 |
- reg[13].I = 0x03007F00; |
|
| 3226 |
- reg[15].I = 0x02000000; |
|
| 3227 |
- reg[16].I = 0x00000000; |
|
| 3228 |
- reg[R13_IRQ].I = 0x03007FA0; |
|
| 3229 |
- reg[R13_SVC].I = 0x03007FE0; |
|
| 3230 |
- armIrqEnable = true; |
|
| 3231 |
- } else {
|
|
| 3232 |
- if(useBios && !skipBios) {
|
|
| 3233 |
- reg[15].I = 0x00000000; |
|
| 3234 |
- armMode = 0x13; |
|
| 3235 |
- armIrqEnable = false; |
|
| 3236 |
- } else {
|
|
| 3237 |
- reg[13].I = 0x03007F00; |
|
| 3238 |
- reg[15].I = 0x08000000; |
|
| 3239 |
- reg[16].I = 0x00000000; |
|
| 3240 |
- reg[R13_IRQ].I = 0x03007FA0; |
|
| 3241 |
- reg[R13_SVC].I = 0x03007FE0; |
|
| 3242 |
- armIrqEnable = true; |
|
| 3243 |
- } |
|
| 3244 |
- } |
|
| 3245 |
- armState = true; |
|
| 3246 |
- C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false; |
|
| 3247 |
- UPDATE_REG(0x00, DISPCNT); |
|
| 3248 |
- UPDATE_REG(0x06, VCOUNT); |
|
| 3249 |
- UPDATE_REG(0x20, BG2PA); |
|
| 3250 |
- UPDATE_REG(0x26, BG2PD); |
|
| 3251 |
- UPDATE_REG(0x30, BG3PA); |
|
| 3252 |
- UPDATE_REG(0x36, BG3PD); |
|
| 3253 |
- UPDATE_REG(0x130, P1); |
|
| 3254 |
- UPDATE_REG(0x88, 0x200); |
|
| 3255 |
- |
|
| 3256 |
- // disable FIQ |
|
| 3257 |
- reg[16].I |= 0x40; |
|
| 3258 |
- |
|
| 3259 |
- CPUUpdateCPSR(); |
|
| 3260 |
- |
|
| 3261 |
- armNextPC = reg[15].I; |
|
| 3262 |
- reg[15].I += 4; |
|
| 3263 |
- |
|
| 3264 |
- // reset internal state |
|
| 3265 |
- holdState = false; |
|
| 3266 |
- holdType = 0; |
|
| 3267 |
- |
|
| 3268 |
- biosProtected[0] = 0x00; |
|
| 3269 |
- biosProtected[1] = 0xf0; |
|
| 3270 |
- biosProtected[2] = 0x29; |
|
| 3271 |
- biosProtected[3] = 0xe1; |
|
| 3272 |
- |
|
| 3273 |
- lcdTicks = (useBios && !skipBios) ? 1008 : 208; |
|
| 3274 |
- timer0On = false; |
|
| 3275 |
- timer0Ticks = 0; |
|
| 3276 |
- timer0Reload = 0; |
|
| 3277 |
- timer0ClockReload = 0; |
|
| 3278 |
- timer1On = false; |
|
| 3279 |
- timer1Ticks = 0; |
|
| 3280 |
- timer1Reload = 0; |
|
| 3281 |
- timer1ClockReload = 0; |
|
| 3282 |
- timer2On = false; |
|
| 3283 |
- timer2Ticks = 0; |
|
| 3284 |
- timer2Reload = 0; |
|
| 3285 |
- timer2ClockReload = 0; |
|
| 3286 |
- timer3On = false; |
|
| 3287 |
- timer3Ticks = 0; |
|
| 3288 |
- timer3Reload = 0; |
|
| 3289 |
- timer3ClockReload = 0; |
|
| 3290 |
- dma0Source = 0; |
|
| 3291 |
- dma0Dest = 0; |
|
| 3292 |
- dma1Source = 0; |
|
| 3293 |
- dma1Dest = 0; |
|
| 3294 |
- dma2Source = 0; |
|
| 3295 |
- dma2Dest = 0; |
|
| 3296 |
- dma3Source = 0; |
|
| 3297 |
- dma3Dest = 0; |
|
| 3298 |
- //cpuSaveGameFunc = flashSaveDecide; |
|
| 3299 |
- //renderLine = mode0RenderLine; |
|
| 3300 |
- fxOn = false; |
|
| 3301 |
- windowOn = false; |
|
| 3302 |
- frameCount = 0; |
|
| 3303 |
- saveType = 0; |
|
| 3304 |
- layerEnable = DISPCNT & layerSettings; |
|
| 3305 |
- |
|
| 3306 |
- //CPUUpdateRenderBuffers(true); |
|
| 3307 |
- |
|
| 3308 |
- for(int i = 0; i < 256; i++) {
|
|
| 3309 |
- map[i].address = (uint8_t *)&dummyAddress; |
|
| 3310 |
- map[i].mask = 0; |
|
| 3311 |
- } |
|
| 3312 |
- |
|
| 3313 |
- map[0].address = bios; |
|
| 3314 |
- map[0].mask = 0x3FFF; |
|
| 3315 |
- map[2].address = workRAM; |
|
| 3316 |
- map[2].mask = 0x3FFFF; |
|
| 3317 |
- map[3].address = internalRAM; |
|
| 3318 |
- map[3].mask = 0x7FFF; |
|
| 3319 |
- map[4].address = ioMem; |
|
| 3320 |
- map[4].mask = 0x3FF; |
|
| 3321 |
- map[5].address = paletteRAM; |
|
| 3322 |
- map[5].mask = 0x3FF; |
|
| 3323 |
- map[6].address = vram; |
|
| 3324 |
- map[6].mask = 0x1FFFF; |
|
| 3325 |
- map[7].address = oam; |
|
| 3326 |
- map[7].mask = 0x3FF; |
|
| 3327 |
- map[8].address = rom; |
|
| 3328 |
- map[8].mask = 0x1FFFFFF; |
|
| 3329 |
- map[9].address = rom; |
|
| 3330 |
- map[9].mask = 0x1FFFFFF; |
|
| 3331 |
- map[10].address = rom; |
|
| 3332 |
- map[10].mask = 0x1FFFFFF; |
|
| 3333 |
- map[12].address = rom; |
|
| 3334 |
- map[12].mask = 0x1FFFFFF; |
|
| 3335 |
- map[14].address = /*flashSaveMemory*/0; |
|
| 3336 |
- map[14].mask = 0xFFFF; |
|
| 3337 |
- |
|
| 3338 |
- //eepromReset(); |
|
| 3339 |
- //flashReset(); |
|
| 3340 |
- |
|
| 3341 |
- soundReset(); |
|
| 3342 |
- |
|
| 3343 |
- //CPUUpdateWindow0(); |
|
| 3344 |
- //CPUUpdateWindow1(); |
|
| 3345 |
- |
|
| 3346 |
- // make sure registers are correctly initialized if not using BIOS |
|
| 3347 |
- if(!useBios) {
|
|
| 3348 |
- if(cpuIsMultiBoot) |
|
| 3349 |
- BIOS_RegisterRamReset(0xfe); |
|
| 3350 |
- else |
|
| 3351 |
- BIOS_RegisterRamReset(0xff); |
|
| 3352 |
- } else {
|
|
| 3353 |
- if(cpuIsMultiBoot) |
|
| 3354 |
- BIOS_RegisterRamReset(0xfe); |
|
| 3355 |
- } |
|
| 3356 |
- |
|
| 3357 |
- /*switch(cpuSaveType) {
|
|
| 3358 |
- case 0: // automatic |
|
| 3359 |
- cpuSramEnabled = true; |
|
| 3360 |
- cpuFlashEnabled = true; |
|
| 3361 |
- cpuEEPROMEnabled = true; |
|
| 3362 |
- cpuEEPROMSensorEnabled = false; |
|
| 3363 |
- saveType = gbaSaveType = 0; |
|
| 3364 |
- break; |
|
| 3365 |
- case 1: // EEPROM |
|
| 3366 |
- cpuSramEnabled = false; |
|
| 3367 |
- cpuFlashEnabled = false; |
|
| 3368 |
- cpuEEPROMEnabled = true; |
|
| 3369 |
- cpuEEPROMSensorEnabled = false; |
|
| 3370 |
- saveType = gbaSaveType = 3; |
|
| 3371 |
- // EEPROM usage is automatically detected |
|
| 3372 |
- break; |
|
| 3373 |
- case 2: // SRAM |
|
| 3374 |
- cpuSramEnabled = true; |
|
| 3375 |
- cpuFlashEnabled = false; |
|
| 3376 |
- cpuEEPROMEnabled = false; |
|
| 3377 |
- cpuEEPROMSensorEnabled = false; |
|
| 3378 |
- cpuSaveGameFunc = sramDelayedWrite; // to insure we detect the write |
|
| 3379 |
- saveType = gbaSaveType = 1; |
|
| 3380 |
- break; |
|
| 3381 |
- case 3: // FLASH |
|
| 3382 |
- cpuSramEnabled = false; |
|
| 3383 |
- cpuFlashEnabled = true; |
|
| 3384 |
- cpuEEPROMEnabled = false; |
|
| 3385 |
- cpuEEPROMSensorEnabled = false; |
|
| 3386 |
- cpuSaveGameFunc = flashDelayedWrite; // to insure we detect the write |
|
| 3387 |
- saveType = gbaSaveType = 2; |
|
| 3388 |
- break; |
|
| 3389 |
- case 4: // EEPROM+Sensor |
|
| 3390 |
- cpuSramEnabled = false; |
|
| 3391 |
- cpuFlashEnabled = false; |
|
| 3392 |
- cpuEEPROMEnabled = true; |
|
| 3393 |
- cpuEEPROMSensorEnabled = true; |
|
| 3394 |
- // EEPROM usage is automatically detected |
|
| 3395 |
- saveType = gbaSaveType = 3; |
|
| 3396 |
- break; |
|
| 3397 |
- case 5: // NONE |
|
| 3398 |
- cpuSramEnabled = false; |
|
| 3399 |
- cpuFlashEnabled = false; |
|
| 3400 |
- cpuEEPROMEnabled = false; |
|
| 3401 |
- cpuEEPROMSensorEnabled = false; |
|
| 3402 |
- // no save at all |
|
| 3403 |
- saveType = gbaSaveType = 5; |
|
| 3404 |
- break; |
|
| 3405 |
- }*/ |
|
| 3406 |
- |
|
| 3407 |
- ARM_PREFETCH; |
|
| 3408 |
- |
|
| 3409 |
- //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 3410 |
- |
|
| 3411 |
- lastTime = /*systemGetClock()*/0; |
|
| 3412 |
- |
|
| 3413 |
- SWITicks = 0; |
|
| 1563 |
+ // clean registers |
|
| 1564 |
+ memset(®[0], 0, sizeof(reg)); |
|
| 1565 |
+ // clean OAM |
|
| 1566 |
+ memset(&oam[0], 0, 0x400); |
|
| 1567 |
+ // clean palette |
|
| 1568 |
+ memset(&paletteRAM[0], 0, 0x400); |
|
| 1569 |
+ // clean vram |
|
| 1570 |
+ memset(&vram[0], 0, 0x20000); |
|
| 1571 |
+ // clean io memory |
|
| 1572 |
+ memset(&ioMem[0], 0, 0x400); |
|
| 1573 |
+ |
|
| 1574 |
+ DISPCNT = 0x0080; |
|
| 1575 |
+ DISPSTAT = 0x0000; |
|
| 1576 |
+ VCOUNT = 0x007E; |
|
| 1577 |
+ BG0CNT = 0x0000; |
|
| 1578 |
+ BG1CNT = 0x0000; |
|
| 1579 |
+ BG2CNT = 0x0000; |
|
| 1580 |
+ BG3CNT = 0x0000; |
|
| 1581 |
+ BG0HOFS = 0x0000; |
|
| 1582 |
+ BG0VOFS = 0x0000; |
|
| 1583 |
+ BG1HOFS = 0x0000; |
|
| 1584 |
+ BG1VOFS = 0x0000; |
|
| 1585 |
+ BG2HOFS = 0x0000; |
|
| 1586 |
+ BG2VOFS = 0x0000; |
|
| 1587 |
+ BG3HOFS = 0x0000; |
|
| 1588 |
+ BG3VOFS = 0x0000; |
|
| 1589 |
+ BG2PA = 0x0100; |
|
| 1590 |
+ BG2PB = 0x0000; |
|
| 1591 |
+ BG2PC = 0x0000; |
|
| 1592 |
+ BG2PD = 0x0100; |
|
| 1593 |
+ BG2X_L = 0x0000; |
|
| 1594 |
+ BG2X_H = 0x0000; |
|
| 1595 |
+ BG2Y_L = 0x0000; |
|
| 1596 |
+ BG2Y_H = 0x0000; |
|
| 1597 |
+ BG3PA = 0x0100; |
|
| 1598 |
+ BG3PB = 0x0000; |
|
| 1599 |
+ BG3PC = 0x0000; |
|
| 1600 |
+ BG3PD = 0x0100; |
|
| 1601 |
+ BG3X_L = 0x0000; |
|
| 1602 |
+ BG3X_H = 0x0000; |
|
| 1603 |
+ BG3Y_L = 0x0000; |
|
| 1604 |
+ BG3Y_H = 0x0000; |
|
| 1605 |
+ WIN0H = 0x0000; |
|
| 1606 |
+ WIN1H = 0x0000; |
|
| 1607 |
+ WIN0V = 0x0000; |
|
| 1608 |
+ WIN1V = 0x0000; |
|
| 1609 |
+ WININ = 0x0000; |
|
| 1610 |
+ WINOUT = 0x0000; |
|
| 1611 |
+ MOSAIC = 0x0000; |
|
| 1612 |
+ BLDMOD = 0x0000; |
|
| 1613 |
+ COLEV = 0x0000; |
|
| 1614 |
+ COLY = 0x0000; |
|
| 1615 |
+ DM0SAD_L = 0x0000; |
|
| 1616 |
+ DM0SAD_H = 0x0000; |
|
| 1617 |
+ DM0DAD_L = 0x0000; |
|
| 1618 |
+ DM0DAD_H = 0x0000; |
|
| 1619 |
+ DM0CNT_L = 0x0000; |
|
| 1620 |
+ DM0CNT_H = 0x0000; |
|
| 1621 |
+ DM1SAD_L = 0x0000; |
|
| 1622 |
+ DM1SAD_H = 0x0000; |
|
| 1623 |
+ DM1DAD_L = 0x0000; |
|
| 1624 |
+ DM1DAD_H = 0x0000; |
|
| 1625 |
+ DM1CNT_L = 0x0000; |
|
| 1626 |
+ DM1CNT_H = 0x0000; |
|
| 1627 |
+ DM2SAD_L = 0x0000; |
|
| 1628 |
+ DM2SAD_H = 0x0000; |
|
| 1629 |
+ DM2DAD_L = 0x0000; |
|
| 1630 |
+ DM2DAD_H = 0x0000; |
|
| 1631 |
+ DM2CNT_L = 0x0000; |
|
| 1632 |
+ DM2CNT_H = 0x0000; |
|
| 1633 |
+ DM3SAD_L = 0x0000; |
|
| 1634 |
+ DM3SAD_H = 0x0000; |
|
| 1635 |
+ DM3DAD_L = 0x0000; |
|
| 1636 |
+ DM3DAD_H = 0x0000; |
|
| 1637 |
+ DM3CNT_L = 0x0000; |
|
| 1638 |
+ DM3CNT_H = 0x0000; |
|
| 1639 |
+ TM0D = 0x0000; |
|
| 1640 |
+ TM0CNT = 0x0000; |
|
| 1641 |
+ TM1D = 0x0000; |
|
| 1642 |
+ TM1CNT = 0x0000; |
|
| 1643 |
+ TM2D = 0x0000; |
|
| 1644 |
+ TM2CNT = 0x0000; |
|
| 1645 |
+ TM3D = 0x0000; |
|
| 1646 |
+ TM3CNT = 0x0000; |
|
| 1647 |
+ P1 = 0x03FF; |
|
| 1648 |
+ IE = 0x0000; |
|
| 1649 |
+ IF = 0x0000; |
|
| 1650 |
+ IME = 0x0000; |
|
| 1651 |
+ |
|
| 1652 |
+ armMode = 0x1F; |
|
| 1653 |
+ |
|
| 1654 |
+ reg[13].I = 0x03007F00; |
|
| 1655 |
+ reg[15].I = cpuIsMultiBoot ? 0x02000000 : 0x08000000; |
|
| 1656 |
+ reg[16].I = 0x00000000; |
|
| 1657 |
+ reg[R13_IRQ].I = 0x03007FA0; |
|
| 1658 |
+ reg[R13_SVC].I = 0x03007FE0; |
|
| 1659 |
+ armIrqEnable = true; |
|
| 1660 |
+ armState = true; |
|
| 1661 |
+ C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false; |
|
| 1662 |
+ UPDATE_REG(0x00, DISPCNT); |
|
| 1663 |
+ UPDATE_REG(0x06, VCOUNT); |
|
| 1664 |
+ UPDATE_REG(0x20, BG2PA); |
|
| 1665 |
+ UPDATE_REG(0x26, BG2PD); |
|
| 1666 |
+ UPDATE_REG(0x30, BG3PA); |
|
| 1667 |
+ UPDATE_REG(0x36, BG3PD); |
|
| 1668 |
+ UPDATE_REG(0x130, P1); |
|
| 1669 |
+ UPDATE_REG(0x88, 0x200); |
|
| 1670 |
+ |
|
| 1671 |
+ // disable FIQ |
|
| 1672 |
+ reg[16].I |= 0x40; |
|
| 1673 |
+ |
|
| 1674 |
+ CPUUpdateCPSR(); |
|
| 1675 |
+ |
|
| 1676 |
+ armNextPC = reg[15].I; |
|
| 1677 |
+ reg[15].I += 4; |
|
| 1678 |
+ |
|
| 1679 |
+ // reset internal state |
|
| 1680 |
+ holdState = false; |
|
| 1681 |
+ holdType = 0; |
|
| 1682 |
+ |
|
| 1683 |
+ biosProtected[0] = 0x00; |
|
| 1684 |
+ biosProtected[1] = 0xf0; |
|
| 1685 |
+ biosProtected[2] = 0x29; |
|
| 1686 |
+ biosProtected[3] = 0xe1; |
|
| 1687 |
+ |
|
| 1688 |
+ lcdTicks = 208; |
|
| 1689 |
+ timer0On = false; |
|
| 1690 |
+ timer0Ticks = 0; |
|
| 1691 |
+ timer0Reload = 0; |
|
| 1692 |
+ timer0ClockReload = 0; |
|
| 1693 |
+ timer1On = false; |
|
| 1694 |
+ timer1Ticks = 0; |
|
| 1695 |
+ timer1Reload = 0; |
|
| 1696 |
+ timer1ClockReload = 0; |
|
| 1697 |
+ timer2On = false; |
|
| 1698 |
+ timer2Ticks = 0; |
|
| 1699 |
+ timer2Reload = 0; |
|
| 1700 |
+ timer2ClockReload = 0; |
|
| 1701 |
+ timer3On = false; |
|
| 1702 |
+ timer3Ticks = 0; |
|
| 1703 |
+ timer3Reload = 0; |
|
| 1704 |
+ timer3ClockReload = 0; |
|
| 1705 |
+ dma0Source = 0; |
|
| 1706 |
+ dma0Dest = 0; |
|
| 1707 |
+ dma1Source = 0; |
|
| 1708 |
+ dma1Dest = 0; |
|
| 1709 |
+ dma2Source = 0; |
|
| 1710 |
+ dma2Dest = 0; |
|
| 1711 |
+ dma3Source = 0; |
|
| 1712 |
+ dma3Dest = 0; |
|
| 1713 |
+ layerEnable = DISPCNT & layerSettings; |
|
| 1714 |
+ |
|
| 1715 |
+ for (int i = 0; i < 256; ++i) |
|
| 1716 |
+ {
|
|
| 1717 |
+ map[i].address = reinterpret_cast<uint8_t *>(&dummyAddress); |
|
| 1718 |
+ map[i].mask = 0; |
|
| 1719 |
+ } |
|
| 1720 |
+ |
|
| 1721 |
+ map[0].address = &bios[0]; |
|
| 1722 |
+ map[0].mask = 0x3FFF; |
|
| 1723 |
+ map[2].address = &workRAM[0]; |
|
| 1724 |
+ map[2].mask = 0x3FFFF; |
|
| 1725 |
+ map[3].address = &internalRAM[0]; |
|
| 1726 |
+ map[3].mask = 0x7FFF; |
|
| 1727 |
+ map[4].address = ioMem; |
|
| 1728 |
+ map[4].mask = 0x3FF; |
|
| 1729 |
+ map[5].address = &paletteRAM[0]; |
|
| 1730 |
+ map[5].mask = 0x3FF; |
|
| 1731 |
+ map[6].address = &vram[0]; |
|
| 1732 |
+ map[6].mask = 0x1FFFF; |
|
| 1733 |
+ map[7].address = &oam[0]; |
|
| 1734 |
+ map[7].mask = 0x3FF; |
|
| 1735 |
+ map[8].address = &rom[0]; |
|
| 1736 |
+ map[8].mask = 0x1FFFFFF; |
|
| 1737 |
+ map[9].address = &rom[0]; |
|
| 1738 |
+ map[9].mask = 0x1FFFFFF; |
|
| 1739 |
+ map[10].address = &rom[0]; |
|
| 1740 |
+ map[10].mask = 0x1FFFFFF; |
|
| 1741 |
+ map[12].address = &rom[0]; |
|
| 1742 |
+ map[12].mask = 0x1FFFFFF; |
|
| 1743 |
+ |
|
| 1744 |
+ soundReset(); |
|
| 1745 |
+ |
|
| 1746 |
+ // make sure registers are correctly initialized if not using BIOS |
|
| 1747 |
+ BIOS_RegisterRamReset(cpuIsMultiBoot ? 0xfe : 0xff); |
|
| 1748 |
+ |
|
| 1749 |
+ ARM_PREFETCH(); |
|
| 1750 |
+ |
|
| 1751 |
+ SWITicks = 0; |
|
| 3414 | 1752 |
} |
| 3415 | 1753 |
|
| 3416 | 1754 |
void CPUInterrupt() |
| 3417 | 1755 |
{
|
| 3418 |
- uint32_t PC = reg[15].I; |
|
| 3419 |
- bool savedState = armState; |
|
| 3420 |
- CPUSwitchMode(0x12, true, false); |
|
| 3421 |
- reg[14].I = PC; |
|
| 3422 |
- if(!savedState) |
|
| 3423 |
- reg[14].I += 2; |
|
| 3424 |
- reg[15].I = 0x18; |
|
| 3425 |
- armState = true; |
|
| 3426 |
- armIrqEnable = false; |
|
| 3427 |
- |
|
| 3428 |
- armNextPC = reg[15].I; |
|
| 3429 |
- reg[15].I += 4; |
|
| 3430 |
- ARM_PREFETCH; |
|
| 3431 |
- |
|
| 3432 |
- // if(!holdState) |
|
| 3433 |
- biosProtected[0] = 0x02; |
|
| 3434 |
- biosProtected[1] = 0xc0; |
|
| 3435 |
- biosProtected[2] = 0x5e; |
|
| 3436 |
- biosProtected[3] = 0xe5; |
|
| 1756 |
+ uint32_t PC = reg[15].I; |
|
| 1757 |
+ bool savedState = armState; |
|
| 1758 |
+ CPUSwitchMode(0x12, true, false); |
|
| 1759 |
+ reg[14].I = PC; |
|
| 1760 |
+ if (!savedState) |
|
| 1761 |
+ reg[14].I += 2; |
|
| 1762 |
+ reg[15].I = 0x18; |
|
| 1763 |
+ armState = true; |
|
| 1764 |
+ armIrqEnable = false; |
|
| 1765 |
+ |
|
| 1766 |
+ armNextPC = reg[15].I; |
|
| 1767 |
+ reg[15].I += 4; |
|
| 1768 |
+ ARM_PREFETCH(); |
|
| 1769 |
+ |
|
| 1770 |
+ //if(!holdState) |
|
| 1771 |
+ biosProtected[0] = 0x02; |
|
| 1772 |
+ biosProtected[1] = 0xc0; |
|
| 1773 |
+ biosProtected[2] = 0x5e; |
|
| 1774 |
+ biosProtected[3] = 0xe5; |
|
| 3437 | 1775 |
} |
| 3438 | 1776 |
|
| 3439 | 1777 |
void CPULoop(int ticks) |
| 3440 | 1778 |
{
|
| 3441 |
- int clockTicks; |
|
| 3442 |
- int timerOverflow = 0; |
|
| 3443 |
- // variable used by the CPU core |
|
| 3444 |
- cpuTotalTicks = 0; |
|
| 3445 |
- |
|
| 3446 |
- // shuffle2: what's the purpose? |
|
| 3447 |
- /*if(gba_link_enabled) |
|
| 3448 |
- cpuNextEvent = 1;*/ |
|
| 3449 |
- |
|
| 3450 |
- cpuBreakLoop = false; |
|
| 3451 |
- cpuNextEvent = CPUUpdateTicks(); |
|
| 3452 |
- if(cpuNextEvent > ticks) |
|
| 3453 |
- cpuNextEvent = ticks; |
|
| 3454 |
- |
|
| 3455 |
- |
|
| 3456 |
- for(;;) {
|
|
| 3457 |
-#ifndef FINAL_VERSION |
|
| 3458 |
- if(systemDebug) {
|
|
| 3459 |
- if(systemDebug >= 10 && !holdState) {
|
|
| 3460 |
- CPUUpdateCPSR(); |
|
| 3461 |
-#ifdef BKPT_SUPPORT |
|
| 3462 |
- if (debugger_last) |
|
| 1779 |
+ int clockTicks; |
|
| 1780 |
+ int timerOverflow = 0; |
|
| 1781 |
+ // variable used by the CPU core |
|
| 1782 |
+ cpuTotalTicks = 0; |
|
| 1783 |
+ |
|
| 1784 |
+ cpuNextEvent = CPUUpdateTicks(); |
|
| 1785 |
+ if (cpuNextEvent > ticks) |
|
| 1786 |
+ cpuNextEvent = ticks; |
|
| 1787 |
+ |
|
| 1788 |
+ for (;;) |
|
| 1789 |
+ {
|
|
| 1790 |
+ if (!holdState && !SWITicks) |
|
| 3463 | 1791 |
{
|
| 3464 |
- winlog("R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
|
|
| 3465 |
- oldreg[0], oldreg[1], oldreg[2], oldreg[3], oldreg[4], oldreg[5], |
|
| 3466 |
- oldreg[6], oldreg[7], oldreg[8], oldreg[9], oldreg[10], oldreg[11], |
|
| 3467 |
- oldreg[12], oldreg[13], oldreg[14], oldreg[15], oldreg[16], |
|
| 3468 |
- oldreg[17]); |
|
| 1792 |
+ if (armState) |
|
| 1793 |
+ {
|
|
| 1794 |
+ if (!armExecute()) |
|
| 1795 |
+ return; |
|
| 1796 |
+ } |
|
| 1797 |
+ else |
|
| 1798 |
+ {
|
|
| 1799 |
+ if (!thumbExecute()) |
|
| 1800 |
+ return; |
|
| 1801 |
+ } |
|
| 1802 |
+ clockTicks = 0; |
|
| 3469 | 1803 |
} |
| 3470 |
-#endif |
|
| 3471 |
- winlog("R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
|
|
| 3472 |
- reg[0].I, reg[1].I, reg[2].I, reg[3].I, reg[4].I, reg[5].I, |
|
| 3473 |
- reg[6].I, reg[7].I, reg[8].I, reg[9].I, reg[10].I, reg[11].I, |
|
| 3474 |
- reg[12].I, reg[13].I, reg[14].I, reg[15].I, reg[16].I, |
|
| 3475 |
- reg[17].I); |
|
| 3476 |
- } else if(!holdState) {
|
|
| 3477 |
- winlog("PC=%08x\n", armNextPC);
|
|
| 3478 |
- } |
|
| 3479 |
- } |
|
| 3480 |
-#endif /* FINAL_VERSION */ |
|
| 3481 |
- |
|
| 3482 |
- if(!holdState && !SWITicks) {
|
|
| 3483 |
- if(armState) {
|
|
| 3484 |
- if (!armExecute()) |
|
| 3485 |
- return; |
|
| 3486 |
- } else {
|
|
| 3487 |
- if (!thumbExecute()) |
|
| 3488 |
- return; |
|
| 3489 |
- } |
|
| 3490 |
- clockTicks = 0; |
|
| 3491 |
- } else |
|
| 3492 |
- clockTicks = CPUUpdateTicks(); |
|
| 3493 |
- |
|
| 3494 |
- cpuTotalTicks += clockTicks; |
|
| 3495 |
- |
|
| 3496 |
- |
|
| 3497 |
- if(cpuTotalTicks >= cpuNextEvent) {
|
|
| 3498 |
- int remainingTicks = cpuTotalTicks - cpuNextEvent; |
|
| 3499 |
- |
|
| 3500 |
- if (SWITicks) |
|
| 3501 |
- {
|
|
| 3502 |
- SWITicks-=clockTicks; |
|
| 3503 |
- if (SWITicks<0) |
|
| 3504 |
- SWITicks = 0; |
|
| 3505 |
- } |
|
| 3506 |
- |
|
| 3507 |
- clockTicks = cpuNextEvent; |
|
| 3508 |
- cpuTotalTicks = 0; |
|
| 3509 |
- |
|
| 3510 |
- updateLoop: |
|
| 3511 |
- |
|
| 3512 |
- if (IRQTicks) |
|
| 3513 |
- {
|
|
| 3514 |
- IRQTicks -= clockTicks; |
|
| 3515 |
- if (IRQTicks<0) |
|
| 3516 |
- IRQTicks = 0; |
|
| 3517 |
- } |
|
| 3518 |
- |
|
| 3519 |
- lcdTicks -= clockTicks; |
|
| 3520 |
- |
|
| 3521 |
- |
|
| 3522 |
- if(lcdTicks <= 0) {
|
|
| 3523 |
- if(DISPSTAT & 1) { // V-BLANK
|
|
| 3524 |
- // if in V-Blank mode, keep computing... |
|
| 3525 |
- if(DISPSTAT & 2) {
|
|
| 3526 |
- lcdTicks += 1008; |
|
| 3527 |
- VCOUNT++; |
|
| 3528 |
- UPDATE_REG(0x06, VCOUNT); |
|
| 3529 |
- DISPSTAT &= 0xFFFD; |
|
| 3530 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 3531 |
- CPUCompareVCOUNT(); |
|
| 3532 |
- } else {
|
|
| 3533 |
- lcdTicks += 224; |
|
| 3534 |
- DISPSTAT |= 2; |
|
| 3535 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 3536 |
- if(DISPSTAT & 16) {
|
|
| 3537 |
- IF |= 2; |
|
| 3538 |
- UPDATE_REG(0x202, IF); |
|
| 3539 |
- } |
|
| 3540 |
- } |
|
| 3541 |
- |
|
| 3542 |
- if(VCOUNT >= 228) { //Reaching last line
|
|
| 3543 |
- DISPSTAT &= 0xFFFC; |
|
| 3544 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 3545 |
- VCOUNT = 0; |
|
| 3546 |
- UPDATE_REG(0x06, VCOUNT); |
|
| 3547 |
- CPUCompareVCOUNT(); |
|
| 3548 |
- } |
|
| 3549 |
- } else {
|
|
| 3550 |
- /*int framesToSkip = *//*systemFrameSkip*//*0; |
|
| 3551 |
- if(speedup) |
|
| 3552 |
- framesToSkip = 9;*/ // try 6 FPS during speedup |
|
| 3553 |
- |
|
| 3554 |
- if(DISPSTAT & 2) {
|
|
| 3555 |
- // if in H-Blank, leave it and move to drawing mode |
|
| 3556 |
- VCOUNT++; |
|
| 3557 |
- UPDATE_REG(0x06, VCOUNT); |
|
| 3558 |
- |
|
| 3559 |
- lcdTicks += 1008; |
|
| 3560 |
- DISPSTAT &= 0xFFFD; |
|
| 3561 |
- if(VCOUNT == 160) {
|
|
| 3562 |
- count++; |
|
| 3563 |
- //systemFrame(); |
|
| 3564 |
- |
|
| 3565 |
- /*if((count % 10) == 0) {
|
|
| 3566 |
- //system10Frames(60); |
|
| 3567 |
- }*/ |
|
| 3568 |
- if(count == 60) {
|
|
| 3569 |
- /*u32 time = *//*systemGetClock()*//*0; |
|
| 3570 |
- if(time != lastTime) {
|
|
| 3571 |
- //u32 t = 100000/(time - lastTime); |
|
| 3572 |
- //systemShowSpeed(t); |
|
| 3573 |
- } else |
|
| 3574 |
- //systemShowSpeed(0); |
|
| 3575 |
- lastTime = time;*/ |
|
| 3576 |
- count = 0; |
|
| 3577 |
- } |
|
| 3578 |
- //u32 joy = 0; |
|
| 3579 |
- // update joystick information |
|
| 3580 |
- /*if(systemReadJoypads()) |
|
| 3581 |
- // read default joystick |
|
| 3582 |
- joy = systemReadJoypad(-1);*/ |
|
| 3583 |
- //P1 = 0x03FF ^ (joy & 0x3FF); |
|
| 3584 |
- /*if(cpuEEPROMSensorEnabled) |
|
| 3585 |
- systemUpdateMotionSensor();*/ |
|
| 3586 |
- /*UPDATE_REG(0x130, P1); |
|
| 3587 |
- u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132])); |
|
| 3588 |
- // this seems wrong, but there are cases where the game |
|
| 3589 |
- // can enter the stop state without requesting an IRQ from |
|
| 3590 |
- // the joypad. |
|
| 3591 |
- if((P1CNT & 0x4000) || stopState) {
|
|
| 3592 |
- u16 p1 = (0x3FF ^ P1) & 0x3FF; |
|
| 3593 |
- if(P1CNT & 0x8000) {
|
|
| 3594 |
- if(p1 == (P1CNT & 0x3FF)) {
|
|
| 3595 |
- IF |= 0x1000; |
|
| 3596 |
- UPDATE_REG(0x202, IF); |
|
| 3597 |
- } |
|
| 3598 |
- } else {
|
|
| 3599 |
- if(p1 & P1CNT) {
|
|
| 3600 |
- IF |= 0x1000; |
|
| 3601 |
- UPDATE_REG(0x202, IF); |
|
| 3602 |
- } |
|
| 3603 |
- } |
|
| 3604 |
- } |
|
| 3605 |
- |
|
| 3606 |
- u32 ext = (joy >> 10);*/ |
|
| 3607 |
- // If no (m) code is enabled, apply the cheats at each LCDline |
|
| 3608 |
- /*if((cheatsEnabled) && (mastercode==0)) |
|
| 3609 |
- remainingTicks += cheatsCheckKeys(P1^0x3FF, ext);*/ |
|
| 3610 |
- /*speedup = (ext & 1) ? true : false; |
|
| 3611 |
- capture = (ext & 2) ? true : false; |
|
| 3612 |
- |
|
| 3613 |
- if(capture && !capturePrevious) {
|
|
| 3614 |
- captureNumber++; |
|
| 3615 |
- //systemScreenCapture(captureNumber); |
|
| 3616 |
- } |
|
| 3617 |
- capturePrevious = capture;*/ |
|
| 3618 |
- |
|
| 3619 |
- DISPSTAT |= 1; |
|
| 3620 |
- DISPSTAT &= 0xFFFD; |
|
| 3621 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 3622 |
- if(DISPSTAT & 0x0008) {
|
|
| 3623 |
- IF |= 1; |
|
| 3624 |
- UPDATE_REG(0x202, IF); |
|
| 3625 |
- } |
|
| 3626 |
- CPUCheckDMA(1, 0x0f); |
|
| 3627 |
- /*if(frameCount >= framesToSkip) {
|
|
| 3628 |
- //systemDrawScreen(); |
|
| 3629 |
- frameCount = 0; |
|
| 3630 |
- } else*/ |
|
| 3631 |
- frameCount++; |
|
| 3632 |
- /*if(systemPauseOnFrame()) |
|
| 3633 |
- ticks = 0;*/ |
|
| 3634 |
- } |
|
| 3635 |
- |
|
| 3636 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 3637 |
- CPUCompareVCOUNT(); |
|
| 3638 |
- |
|
| 3639 |
- } else {
|
|
| 3640 |
- /*if(frameCount >= framesToSkip) |
|
| 3641 |
- {*/
|
|
| 3642 |
- /*(*renderLine)(); |
|
| 3643 |
- switch(systemColorDepth) {
|
|
| 3644 |
- case 16: |
|
| 3645 |
- {
|
|
| 3646 |
- u16 *dest = (u16 *)pix + 242 * (VCOUNT+1); |
|
| 3647 |
- for(int x = 0; x < 240;) {
|
|
| 3648 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3649 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3650 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3651 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3652 |
- |
|
| 3653 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3654 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3655 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3656 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3657 |
- |
|
| 3658 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3659 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3660 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3661 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3662 |
- |
|
| 3663 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3664 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3665 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3666 |
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3667 |
- } |
|
| 3668 |
- // for filters that read past the screen |
|
| 3669 |
- *dest++ = 0; |
|
| 3670 |
- } |
|
| 3671 |
- break; |
|
| 3672 |
- case 24: |
|
| 3673 |
- {
|
|
| 3674 |
- u8 *dest = (u8 *)pix + 240 * VCOUNT * 3; |
|
| 3675 |
- for(int x = 0; x < 240;) {
|
|
| 3676 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3677 |
- dest += 3; |
|
| 3678 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3679 |
- dest += 3; |
|
| 3680 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3681 |
- dest += 3; |
|
| 3682 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3683 |
- dest += 3; |
|
| 3684 |
- |
|
| 3685 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3686 |
- dest += 3; |
|
| 3687 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3688 |
- dest += 3; |
|
| 3689 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3690 |
- dest += 3; |
|
| 3691 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3692 |
- dest += 3; |
|
| 3693 |
- |
|
| 3694 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3695 |
- dest += 3; |
|
| 3696 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3697 |
- dest += 3; |
|
| 3698 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3699 |
- dest += 3; |
|
| 3700 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3701 |
- dest += 3; |
|
| 3702 |
- |
|
| 3703 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3704 |
- dest += 3; |
|
| 3705 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3706 |
- dest += 3; |
|
| 3707 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3708 |
- dest += 3; |
|
| 3709 |
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3710 |
- dest += 3; |
|
| 3711 |
- } |
|
| 3712 |
- } |
|
| 3713 |
- break; |
|
| 3714 |
- case 32: |
|
| 3715 |
- {
|
|
| 3716 |
- u32 *dest = (u32 *)pix + 241 * (VCOUNT+1); |
|
| 3717 |
- for(int x = 0; x < 240; ) {
|
|
| 3718 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3719 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3720 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3721 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3722 |
- |
|
| 3723 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3724 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3725 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3726 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3727 |
- |
|
| 3728 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3729 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3730 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3731 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3732 |
- |
|
| 3733 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3734 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3735 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3736 |
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3737 |
- } |
|
| 3738 |
- } |
|
| 3739 |
- break; |
|
| 3740 |
- }*/ |
|
| 3741 |
- /*}*/ |
|
| 3742 |
- // entering H-Blank |
|
| 3743 |
- DISPSTAT |= 2; |
|
| 3744 |
- UPDATE_REG(0x04, DISPSTAT); |
|
| 3745 |
- lcdTicks += 224; |
|
| 3746 |
- CPUCheckDMA(2, 0x0f); |
|
| 3747 |
- if(DISPSTAT & 16) {
|
|
| 3748 |
- IF |= 2; |
|
| 3749 |
- UPDATE_REG(0x202, IF); |
|
| 3750 |
- } |
|
| 3751 |
- } |
|
| 3752 |
- } |
|
| 3753 |
- } |
|
| 3754 |
- |
|
| 3755 |
- // we shouldn't be doing sound in stop state, but we loose synchronization |
|
| 3756 |
- // if sound is disabled, so in stop state, soundTick will just produce |
|
| 3757 |
- // mute sound |
|
| 3758 |
- soundTicks -= clockTicks; |
|
| 3759 |
- if(soundTicks <= 0) {
|
|
| 3760 |
- psoundTickfn(); |
|
| 3761 |
- soundTicks += SOUND_CLOCK_TICKS; |
|
| 3762 |
- } |
|
| 3763 |
- |
|
| 3764 |
- if(!stopState) {
|
|
| 3765 |
- if(timer0On) {
|
|
| 3766 |
- timer0Ticks -= clockTicks; |
|
| 3767 |
- if(timer0Ticks <= 0) {
|
|
| 3768 |
- timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload; |
|
| 3769 |
- timerOverflow |= 1; |
|
| 3770 |
- soundTimerOverflow(0); |
|
| 3771 |
- if(TM0CNT & 0x40) {
|
|
| 3772 |
- IF |= 0x08; |
|
| 3773 |
- UPDATE_REG(0x202, IF); |
|
| 3774 |
- } |
|
| 3775 |
- } |
|
| 3776 |
- TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload); |
|
| 3777 |
- UPDATE_REG(0x100, TM0D); |
|
| 3778 |
- } |
|
| 3779 |
- |
|
| 3780 |
- if(timer1On) {
|
|
| 3781 |
- if(TM1CNT & 4) {
|
|
| 3782 |
- if(timerOverflow & 1) {
|
|
| 3783 |
- TM1D++; |
|
| 3784 |
- if(TM1D == 0) {
|
|
| 3785 |
- TM1D += timer1Reload; |
|
| 3786 |
- timerOverflow |= 2; |
|
| 3787 |
- soundTimerOverflow(1); |
|
| 3788 |
- if(TM1CNT & 0x40) {
|
|
| 3789 |
- IF |= 0x10; |
|
| 3790 |
- UPDATE_REG(0x202, IF); |
|
| 3791 |
- } |
|
| 3792 |
- } |
|
| 3793 |
- UPDATE_REG(0x104, TM1D); |
|
| 3794 |
- } |
|
| 3795 |
- } else {
|
|
| 3796 |
- timer1Ticks -= clockTicks; |
|
| 3797 |
- if(timer1Ticks <= 0) {
|
|
| 3798 |
- timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload; |
|
| 3799 |
- timerOverflow |= 2; |
|
| 3800 |
- soundTimerOverflow(1); |
|
| 3801 |
- if(TM1CNT & 0x40) {
|
|
| 3802 |
- IF |= 0x10; |
|
| 3803 |
- UPDATE_REG(0x202, IF); |
|
| 3804 |
- } |
|
| 3805 |
- } |
|
| 3806 |
- TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload); |
|
| 3807 |
- UPDATE_REG(0x104, TM1D); |
|
| 3808 |
- } |
|
| 3809 |
- } |
|
| 3810 |
- |
|
| 3811 |
- if(timer2On) {
|
|
| 3812 |
- if(TM2CNT & 4) {
|
|
| 3813 |
- if(timerOverflow & 2) {
|
|
| 3814 |
- TM2D++; |
|
| 3815 |
- if(TM2D == 0) {
|
|
| 3816 |
- TM2D += timer2Reload; |
|
| 3817 |
- timerOverflow |= 4; |
|
| 3818 |
- if(TM2CNT & 0x40) {
|
|
| 3819 |
- IF |= 0x20; |
|
| 3820 |
- UPDATE_REG(0x202, IF); |
|
| 3821 |
- } |
|
| 3822 |
- } |
|
| 3823 |
- UPDATE_REG(0x108, TM2D); |
|
| 3824 |
- } |
|
| 3825 |
- } else {
|
|
| 3826 |
- timer2Ticks -= clockTicks; |
|
| 3827 |
- if(timer2Ticks <= 0) {
|
|
| 3828 |
- timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload; |
|
| 3829 |
- timerOverflow |= 4; |
|
| 3830 |
- if(TM2CNT & 0x40) {
|
|
| 3831 |
- IF |= 0x20; |
|
| 3832 |
- UPDATE_REG(0x202, IF); |
|
| 3833 |
- } |
|
| 3834 |
- } |
|
| 3835 |
- TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload); |
|
| 3836 |
- UPDATE_REG(0x108, TM2D); |
|
| 3837 |
- } |
|
| 3838 |
- } |
|
| 3839 |
- |
|
| 3840 |
- if(timer3On) {
|
|
| 3841 |
- if(TM3CNT & 4) {
|
|
| 3842 |
- if(timerOverflow & 4) {
|
|
| 3843 |
- TM3D++; |
|
| 3844 |
- if(TM3D == 0) {
|
|
| 3845 |
- TM3D += timer3Reload; |
|
| 3846 |
- if(TM3CNT & 0x40) {
|
|
| 3847 |
- IF |= 0x40; |
|
| 3848 |
- UPDATE_REG(0x202, IF); |
|
| 3849 |
- } |
|
| 3850 |
- } |
|
| 3851 |
- UPDATE_REG(0x10C, TM3D); |
|
| 3852 |
- } |
|
| 3853 |
- } else {
|
|
| 3854 |
- timer3Ticks -= clockTicks; |
|
| 3855 |
- if(timer3Ticks <= 0) {
|
|
| 3856 |
- timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload; |
|
| 3857 |
- if(TM3CNT & 0x40) {
|
|
| 3858 |
- IF |= 0x40; |
|
| 3859 |
- UPDATE_REG(0x202, IF); |
|
| 3860 |
- } |
|
| 3861 |
- } |
|
| 3862 |
- TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload); |
|
| 3863 |
- UPDATE_REG(0x10C, TM3D); |
|
| 3864 |
- } |
|
| 3865 |
- } |
|
| 3866 |
- } |
|
| 3867 |
- |
|
| 3868 |
- timerOverflow = 0; |
|
| 3869 |
- |
|
| 3870 |
- |
|
| 3871 |
- |
|
| 3872 |
-#ifdef PROFILING |
|
| 3873 |
- profilingTicks -= clockTicks; |
|
| 3874 |
- if(profilingTicks <= 0) {
|
|
| 3875 |
- profilingTicks += profilingTicksReload; |
|
| 3876 |
- if(profilSegment) {
|
|
| 3877 |
- profile_segment *seg = profilSegment; |
|
| 3878 |
- do {
|
|
| 3879 |
- uint16_t *b = (uint16_t *)seg->sbuf; |
|
| 3880 |
- int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale)/0x10000; |
|
| 3881 |
- if(pc >= 0 && pc < seg->ssiz) {
|
|
| 3882 |
- b[pc]++; |
|
| 3883 |
- break; |
|
| 3884 |
- } |
|
| 3885 |
- |
|
| 3886 |
- seg = seg->next; |
|
| 3887 |
- } while(seg); |
|
| 3888 |
- } |
|
| 3889 |
- } |
|
| 3890 |
-#endif |
|
| 1804 |
+ else |
|
| 1805 |
+ clockTicks = CPUUpdateTicks(); |
|
| 3891 | 1806 |
|
| 3892 |
- ticks -= clockTicks; |
|
| 3893 |
- |
|
| 3894 |
- /*if (gba_joybus_enabled) |
|
| 3895 |
- JoyBusUpdate(clockTicks); |
|
| 3896 |
- |
|
| 3897 |
- if (gba_link_enabled) |
|
| 3898 |
- LinkUpdate(clockTicks);*/ |
|
| 3899 |
- |
|
| 3900 |
- cpuNextEvent = CPUUpdateTicks(); |
|
| 3901 |
- |
|
| 3902 |
- if(cpuDmaTicksToUpdate > 0) {
|
|
| 3903 |
- if(cpuDmaTicksToUpdate > cpuNextEvent) |
|
| 3904 |
- clockTicks = cpuNextEvent; |
|
| 3905 |
- else |
|
| 3906 |
- clockTicks = cpuDmaTicksToUpdate; |
|
| 3907 |
- cpuDmaTicksToUpdate -= clockTicks; |
|
| 3908 |
- if(cpuDmaTicksToUpdate < 0) |
|
| 3909 |
- cpuDmaTicksToUpdate = 0; |
|
| 3910 |
- goto updateLoop; |
|
| 3911 |
- } |
|
| 3912 |
- |
|
| 3913 |
- // shuffle2: what's the purpose? |
|
| 3914 |
- /*if(gba_link_enabled) |
|
| 3915 |
- cpuNextEvent = 1;*/ |
|
| 3916 |
- |
|
| 3917 |
- if(IF && (IME & 1) && armIrqEnable) {
|
|
| 3918 |
- int res = IF & IE; |
|
| 3919 |
- if(stopState) |
|
| 3920 |
- res &= 0x3080; |
|
| 3921 |
- if(res) {
|
|
| 3922 |
- if (intState) |
|
| 3923 |
- {
|
|
| 3924 |
- if (!IRQTicks) |
|
| 3925 |
- {
|
|
| 3926 |
- CPUInterrupt(); |
|
| 3927 |
- intState = false; |
|
| 3928 |
- holdState = false; |
|
| 3929 |
- stopState = false; |
|
| 3930 |
- holdType = 0; |
|
| 3931 |
- } |
|
| 3932 |
- } |
|
| 3933 |
- else |
|
| 3934 |
- {
|
|
| 3935 |
- if (!holdState) |
|
| 3936 |
- {
|
|
| 3937 |
- intState = true; |
|
| 3938 |
- IRQTicks=7; |
|
| 3939 |
- if (cpuNextEvent> IRQTicks) |
|
| 3940 |
- cpuNextEvent = IRQTicks; |
|
| 3941 |
- } |
|
| 3942 |
- else |
|
| 3943 |
- {
|
|
| 3944 |
- CPUInterrupt(); |
|
| 3945 |
- holdState = false; |
|
| 3946 |
- stopState = false; |
|
| 3947 |
- holdType = 0; |
|
| 3948 |
- } |
|
| 3949 |
- } |
|
| 3950 |
- |
|
| 3951 |
- // Stops the SWI Ticks emulation if an IRQ is executed |
|
| 3952 |
- //(to avoid problems with nested IRQ/SWI) |
|
| 3953 |
- if (SWITicks) |
|
| 3954 |
- SWITicks = 0; |
|
| 3955 |
- } |
|
| 3956 |
- } |
|
| 3957 |
- |
|
| 3958 |
- if(remainingTicks > 0) {
|
|
| 3959 |
- if(remainingTicks > cpuNextEvent) |
|
| 3960 |
- clockTicks = cpuNextEvent; |
|
| 3961 |
- else |
|
| 3962 |
- clockTicks = remainingTicks; |
|
| 3963 |
- remainingTicks -= clockTicks; |
|
| 3964 |
- if(remainingTicks < 0) |
|
| 3965 |
- remainingTicks = 0; |
|
| 3966 |
- goto updateLoop; |
|
| 3967 |
- } |
|
| 3968 |
- |
|
| 3969 |
- if (timerOnOffDelay) |
|
| 3970 |
- applyTimer(); |
|
| 3971 |
- |
|
| 3972 |
- if(cpuNextEvent > ticks) |
|
| 3973 |
- cpuNextEvent = ticks; |
|
| 3974 |
- |
|
| 3975 |
- if(ticks <= 0 || cpuBreakLoop) |
|
| 3976 |
- break; |
|
| 3977 |
- |
|
| 3978 |
- } |
|
| 3979 |
- } |
|
| 3980 |
-} |
|
| 1807 |
+ cpuTotalTicks += clockTicks; |
|
| 3981 | 1808 |
|
| 3982 |
- |
|
| 3983 |
- |
|
| 3984 |
-/*struct EmulatedSystem GBASystem = {
|
|
| 3985 |
- // emuMain |
|
| 3986 |
- CPULoop, |
|
| 3987 |
- // emuReset |
|
| 3988 |
- CPUReset, |
|
| 3989 |
- // emuCleanUp |
|
| 3990 |
- CPUCleanUp, |
|
| 3991 |
- // emuReadBattery |
|
| 3992 |
- CPUReadBatteryFile, |
|
| 3993 |
- // emuWriteBattery |
|
| 3994 |
- CPUWriteBatteryFile, |
|
| 3995 |
- // emuReadState |
|
| 3996 |
- CPUReadState, |
|
| 3997 |
- // emuWriteState |
|
| 3998 |
- CPUWriteState, |
|
| 3999 |
- // emuReadMemState |
|
| 4000 |
- CPUReadMemState, |
|
| 4001 |
- // emuWriteMemState |
|
| 4002 |
- CPUWriteMemState, |
|
| 4003 |
- // emuWritePNG |
|
| 4004 |
- CPUWritePNGFile, |
|
| 4005 |
- // emuWriteBMP |
|
| 4006 |
- CPUWriteBMPFile, |
|
| 4007 |
- // emuUpdateCPSR |
|
| 4008 |
- CPUUpdateCPSR, |
|
| 4009 |
- // emuHasDebugger |
|
| 4010 |
- true, |
|
| 4011 |
- // emuCount |
|
| 4012 |
-#ifdef FINAL_VERSION |
|
| 4013 |
- 250000 |
|
| 4014 |
-#else |
|
| 4015 |
- 5000 |
|
| 4016 |
-#endif |
|
| 4017 |
-};*/ |
|
| 1809 |
+ if (cpuTotalTicks >= cpuNextEvent) |
|
| 1810 |
+ {
|
|
| 1811 |
+ int remainingTicks = cpuTotalTicks - cpuNextEvent; |
|
| 1812 |
+ |
|
| 1813 |
+ if (SWITicks) |
|
| 1814 |
+ {
|
|
| 1815 |
+ SWITicks -= clockTicks; |
|
| 1816 |
+ if (SWITicks < 0) |
|
| 1817 |
+ SWITicks = 0; |
|
| 1818 |
+ } |
|
| 1819 |
+ |
|
| 1820 |
+ clockTicks = cpuNextEvent; |
|
| 1821 |
+ cpuTotalTicks = 0; |
|
| 1822 |
+ |
|
| 1823 |
+ updateLoop: |
|
| 1824 |
+ |
|
| 1825 |
+ if (IRQTicks) |
|
| 1826 |
+ {
|
|
| 1827 |
+ IRQTicks -= clockTicks; |
|
| 1828 |
+ if (IRQTicks < 0) |
|
| 1829 |
+ IRQTicks = 0; |
|
| 1830 |
+ } |
|
| 1831 |
+ |
|
| 1832 |
+ lcdTicks -= clockTicks; |
|
| 1833 |
+ |
|
| 1834 |
+ if (lcdTicks <= 0) |
|
| 1835 |
+ {
|
|
| 1836 |
+ if (DISPSTAT & 1) // V-BLANK |
|
| 1837 |
+ {
|
|
| 1838 |
+ // if in V-Blank mode, keep computing... |
|
| 1839 |
+ if (DISPSTAT & 2) |
|
| 1840 |
+ {
|
|
| 1841 |
+ lcdTicks += 1008; |
|
| 1842 |
+ ++VCOUNT; |
|
| 1843 |
+ UPDATE_REG(0x06, VCOUNT); |
|
| 1844 |
+ DISPSTAT &= 0xFFFD; |
|
| 1845 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 1846 |
+ CPUCompareVCOUNT(); |
|
| 1847 |
+ } |
|
| 1848 |
+ else |
|
| 1849 |
+ {
|
|
| 1850 |
+ lcdTicks += 224; |
|
| 1851 |
+ DISPSTAT |= 2; |
|
| 1852 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 1853 |
+ if (DISPSTAT & 16) |
|
| 1854 |
+ {
|
|
| 1855 |
+ IF |= 2; |
|
| 1856 |
+ UPDATE_REG(0x202, IF); |
|
| 1857 |
+ } |
|
| 1858 |
+ } |
|
| 1859 |
+ |
|
| 1860 |
+ if (VCOUNT >= 228) //Reaching last line |
|
| 1861 |
+ {
|
|
| 1862 |
+ DISPSTAT &= 0xFFFC; |
|
| 1863 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 1864 |
+ VCOUNT = 0; |
|
| 1865 |
+ UPDATE_REG(0x06, VCOUNT); |
|
| 1866 |
+ CPUCompareVCOUNT(); |
|
| 1867 |
+ } |
|
| 1868 |
+ } |
|
| 1869 |
+ else |
|
| 1870 |
+ {
|
|
| 1871 |
+ if (DISPSTAT & 2) |
|
| 1872 |
+ {
|
|
| 1873 |
+ // if in H-Blank, leave it and move to drawing mode |
|
| 1874 |
+ ++VCOUNT; |
|
| 1875 |
+ UPDATE_REG(0x06, VCOUNT); |
|
| 1876 |
+ |
|
| 1877 |
+ lcdTicks += 1008; |
|
| 1878 |
+ DISPSTAT &= 0xFFFD; |
|
| 1879 |
+ if (VCOUNT == 160) |
|
| 1880 |
+ {
|
|
| 1881 |
+ ++count; |
|
| 1882 |
+ if (count == 60) |
|
| 1883 |
+ count = 0; |
|
| 1884 |
+ |
|
| 1885 |
+ DISPSTAT |= 1; |
|
| 1886 |
+ DISPSTAT &= 0xFFFD; |
|
| 1887 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 1888 |
+ if (DISPSTAT & 0x0008) |
|
| 1889 |
+ {
|
|
| 1890 |
+ IF |= 1; |
|
| 1891 |
+ UPDATE_REG(0x202, IF); |
|
| 1892 |
+ } |
|
| 1893 |
+ CPUCheckDMA(1, 0x0f); |
|
| 1894 |
+ } |
|
| 1895 |
+ |
|
| 1896 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 1897 |
+ CPUCompareVCOUNT(); |
|
| 1898 |
+ } |
|
| 1899 |
+ else |
|
| 1900 |
+ {
|
|
| 1901 |
+ // entering H-Blank |
|
| 1902 |
+ DISPSTAT |= 2; |
|
| 1903 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 1904 |
+ lcdTicks += 224; |
|
| 1905 |
+ CPUCheckDMA(2, 0x0f); |
|
| 1906 |
+ if (DISPSTAT & 16) |
|
| 1907 |
+ {
|
|
| 1908 |
+ IF |= 2; |
|
| 1909 |
+ UPDATE_REG(0x202, IF); |
|
| 1910 |
+ } |
|
| 1911 |
+ } |
|
| 1912 |
+ } |
|
| 1913 |
+ } |
|
| 1914 |
+ |
|
| 1915 |
+ // we shouldn't be doing sound in stop state, but we loose synchronization |
|
| 1916 |
+ // if sound is disabled, so in stop state, soundTick will just produce |
|
| 1917 |
+ // mute sound |
|
| 1918 |
+ soundTicks -= clockTicks; |
|
| 1919 |
+ if (soundTicks <= 0) |
|
| 1920 |
+ {
|
|
| 1921 |
+ psoundTickfn(); |
|
| 1922 |
+ soundTicks += SOUND_CLOCK_TICKS; |
|
| 1923 |
+ } |
|
| 1924 |
+ |
|
| 1925 |
+ if (!stopState) |
|
| 1926 |
+ {
|
|
| 1927 |
+ if (timer0On) |
|
| 1928 |
+ {
|
|
| 1929 |
+ timer0Ticks -= clockTicks; |
|
| 1930 |
+ if (timer0Ticks <= 0) |
|
| 1931 |
+ {
|
|
| 1932 |
+ timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload; |
|
| 1933 |
+ timerOverflow |= 1; |
|
| 1934 |
+ soundTimerOverflow(0); |
|
| 1935 |
+ if (TM0CNT & 0x40) |
|
| 1936 |
+ {
|
|
| 1937 |
+ IF |= 0x08; |
|
| 1938 |
+ UPDATE_REG(0x202, IF); |
|
| 1939 |
+ } |
|
| 1940 |
+ } |
|
| 1941 |
+ TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload); |
|
| 1942 |
+ UPDATE_REG(0x100, TM0D); |
|
| 1943 |
+ } |
|
| 1944 |
+ |
|
| 1945 |
+ if (timer1On) |
|
| 1946 |
+ {
|
|
| 1947 |
+ if (TM1CNT & 4) |
|
| 1948 |
+ {
|
|
| 1949 |
+ if (timerOverflow & 1) |
|
| 1950 |
+ {
|
|
| 1951 |
+ ++TM1D; |
|
| 1952 |
+ if (!TM1D) |
|
| 1953 |
+ {
|
|
| 1954 |
+ TM1D += timer1Reload; |
|
| 1955 |
+ timerOverflow |= 2; |
|
| 1956 |
+ soundTimerOverflow(1); |
|
| 1957 |
+ if (TM1CNT & 0x40) |
|
| 1958 |
+ {
|
|
| 1959 |
+ IF |= 0x10; |
|
| 1960 |
+ UPDATE_REG(0x202, IF); |
|
| 1961 |
+ } |
|
| 1962 |
+ } |
|
| 1963 |
+ UPDATE_REG(0x104, TM1D); |
|
| 1964 |
+ } |
|
| 1965 |
+ } |
|
| 1966 |
+ else |
|
| 1967 |
+ {
|
|
| 1968 |
+ timer1Ticks -= clockTicks; |
|
| 1969 |
+ if (timer1Ticks <= 0) |
|
| 1970 |
+ {
|
|
| 1971 |
+ timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload; |
|
| 1972 |
+ timerOverflow |= 2; |
|
| 1973 |
+ soundTimerOverflow(1); |
|
| 1974 |
+ if (TM1CNT & 0x40) |
|
| 1975 |
+ {
|
|
| 1976 |
+ IF |= 0x10; |
|
| 1977 |
+ UPDATE_REG(0x202, IF); |
|
| 1978 |
+ } |
|
| 1979 |
+ } |
|
| 1980 |
+ TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload); |
|
| 1981 |
+ UPDATE_REG(0x104, TM1D); |
|
| 1982 |
+ } |
|
| 1983 |
+ } |
|
| 1984 |
+ |
|
| 1985 |
+ if (timer2On) |
|
| 1986 |
+ {
|
|
| 1987 |
+ if (TM2CNT & 4) |
|
| 1988 |
+ {
|
|
| 1989 |
+ if (timerOverflow & 2) |
|
| 1990 |
+ {
|
|
| 1991 |
+ ++TM2D; |
|
| 1992 |
+ if (!TM2D) |
|
| 1993 |
+ {
|
|
| 1994 |
+ TM2D += timer2Reload; |
|
| 1995 |
+ timerOverflow |= 4; |
|
| 1996 |
+ if (TM2CNT & 0x40) |
|
| 1997 |
+ {
|
|
| 1998 |
+ IF |= 0x20; |
|
| 1999 |
+ UPDATE_REG(0x202, IF); |
|
| 2000 |
+ } |
|
| 2001 |
+ } |
|
| 2002 |
+ UPDATE_REG(0x108, TM2D); |
|
| 2003 |
+ } |
|
| 2004 |
+ } |
|
| 2005 |
+ else |
|
| 2006 |
+ {
|
|
| 2007 |
+ timer2Ticks -= clockTicks; |
|
| 2008 |
+ if (timer2Ticks <= 0) |
|
| 2009 |
+ {
|
|
| 2010 |
+ timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload; |
|
| 2011 |
+ timerOverflow |= 4; |
|
| 2012 |
+ if (TM2CNT & 0x40) |
|
| 2013 |
+ {
|
|
| 2014 |
+ IF |= 0x20; |
|
| 2015 |
+ UPDATE_REG(0x202, IF); |
|
| 2016 |
+ } |
|
| 2017 |
+ } |
|
| 2018 |
+ TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload); |
|
| 2019 |
+ UPDATE_REG(0x108, TM2D); |
|
| 2020 |
+ } |
|
| 2021 |
+ } |
|
| 2022 |
+ |
|
| 2023 |
+ if (timer3On) |
|
| 2024 |
+ {
|
|
| 2025 |
+ if (TM3CNT & 4) |
|
| 2026 |
+ {
|
|
| 2027 |
+ if (timerOverflow & 4) |
|
| 2028 |
+ {
|
|
| 2029 |
+ ++TM3D; |
|
| 2030 |
+ if (!TM3D) |
|
| 2031 |
+ {
|
|
| 2032 |
+ TM3D += timer3Reload; |
|
| 2033 |
+ if (TM3CNT & 0x40) |
|
| 2034 |
+ {
|
|
| 2035 |
+ IF |= 0x40; |
|
| 2036 |
+ UPDATE_REG(0x202, IF); |
|
| 2037 |
+ } |
|
| 2038 |
+ } |
|
| 2039 |
+ UPDATE_REG(0x10C, TM3D); |
|
| 2040 |
+ } |
|
| 2041 |
+ } |
|
| 2042 |
+ else |
|
| 2043 |
+ {
|
|
| 2044 |
+ timer3Ticks -= clockTicks; |
|
| 2045 |
+ if (timer3Ticks <= 0) |
|
| 2046 |
+ {
|
|
| 2047 |
+ timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload; |
|
| 2048 |
+ if (TM3CNT & 0x40) |
|
| 2049 |
+ {
|
|
| 2050 |
+ IF |= 0x40; |
|
| 2051 |
+ UPDATE_REG(0x202, IF); |
|
| 2052 |
+ } |
|
| 2053 |
+ } |
|
| 2054 |
+ TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload); |
|
| 2055 |
+ UPDATE_REG(0x10C, TM3D); |
|
| 2056 |
+ } |
|
| 2057 |
+ } |
|
| 2058 |
+ } |
|
| 2059 |
+ |
|
| 2060 |
+ timerOverflow = 0; |
|
| 2061 |
+ |
|
| 2062 |
+ ticks -= clockTicks; |
|
| 2063 |
+ |
|
| 2064 |
+ cpuNextEvent = CPUUpdateTicks(); |
|
| 2065 |
+ |
|
| 2066 |
+ if (cpuDmaTicksToUpdate > 0) |
|
| 2067 |
+ {
|
|
| 2068 |
+ if (cpuDmaTicksToUpdate > cpuNextEvent) |
|
| 2069 |
+ clockTicks = cpuNextEvent; |
|
| 2070 |
+ else |
|
| 2071 |
+ clockTicks = cpuDmaTicksToUpdate; |
|
| 2072 |
+ cpuDmaTicksToUpdate -= clockTicks; |
|
| 2073 |
+ if (cpuDmaTicksToUpdate < 0) |
|
| 2074 |
+ cpuDmaTicksToUpdate = 0; |
|
| 2075 |
+ goto updateLoop; |
|
| 2076 |
+ } |
|
| 2077 |
+ |
|
| 2078 |
+ if (IF && (IME & 1) && armIrqEnable) |
|
| 2079 |
+ {
|
|
| 2080 |
+ int res = IF & IE; |
|
| 2081 |
+ if (stopState) |
|
| 2082 |
+ res &= 0x3080; |
|
| 2083 |
+ if (res) |
|
| 2084 |
+ {
|
|
| 2085 |
+ if (intState) |
|
| 2086 |
+ {
|
|
| 2087 |
+ if (!IRQTicks) |
|
| 2088 |
+ {
|
|
| 2089 |
+ CPUInterrupt(); |
|
| 2090 |
+ intState = false; |
|
| 2091 |
+ holdState = false; |
|
| 2092 |
+ stopState = false; |
|
| 2093 |
+ holdType = 0; |
|
| 2094 |
+ } |
|
| 2095 |
+ } |
|
| 2096 |
+ else |
|
| 2097 |
+ {
|
|
| 2098 |
+ if (!holdState) |
|
| 2099 |
+ {
|
|
| 2100 |
+ intState = true; |
|
| 2101 |
+ IRQTicks = 7; |
|
| 2102 |
+ if (cpuNextEvent> IRQTicks) |
|
| 2103 |
+ cpuNextEvent = IRQTicks; |
|
| 2104 |
+ } |
|
| 2105 |
+ else |
|
| 2106 |
+ {
|
|
| 2107 |
+ CPUInterrupt(); |
|
| 2108 |
+ holdState = false; |
|
| 2109 |
+ stopState = false; |
|
| 2110 |
+ holdType = 0; |
|
| 2111 |
+ } |
|
| 2112 |
+ } |
|
| 2113 |
+ |
|
| 2114 |
+ // Stops the SWI Ticks emulation if an IRQ is executed |
|
| 2115 |
+ // (to avoid problems with nested IRQ/SWI) |
|
| 2116 |
+ if (SWITicks) |
|
| 2117 |
+ SWITicks = 0; |
|
| 2118 |
+ } |
|
| 2119 |
+ } |
|
| 2120 |
+ |
|
| 2121 |
+ if (remainingTicks > 0) |
|
| 2122 |
+ {
|
|
| 2123 |
+ if (remainingTicks > cpuNextEvent) |
|
| 2124 |
+ clockTicks = cpuNextEvent; |
|
| 2125 |
+ else |
|
| 2126 |
+ clockTicks = remainingTicks; |
|
| 2127 |
+ remainingTicks -= clockTicks; |
|
| 2128 |
+ if (remainingTicks < 0) |
|
| 2129 |
+ remainingTicks = 0; |
|
| 2130 |
+ goto updateLoop; |
|
| 2131 |
+ } |
|
| 2132 |
+ |
|
| 2133 |
+ if (timerOnOffDelay) |
|
| 2134 |
+ applyTimer(); |
|
| 2135 |
+ |
|
| 2136 |
+ if (cpuNextEvent > ticks) |
|
| 2137 |
+ cpuNextEvent = ticks; |
|
| 2138 |
+ |
|
| 2139 |
+ if (ticks <= 0) |
|
| 2140 |
+ break; |
|
| 2141 |
+ } |
|
| 2142 |
+ } |
|
| 2143 |
+} |
| ... | ... |
@@ -22,7 +22,7 @@ |
| 22 | 22 |
//#include "agbprint.h" |
| 23 | 23 |
//#include "GBALink.h" |
| 24 | 24 |
|
| 25 |
-extern int mapgsf(u8* a, int l, int &s); |
|
| 25 |
+extern int mapgsf(uint8_t* a, int l, int &s); |
|
| 26 | 26 |
|
| 27 | 27 |
#ifdef PROFILING |
| 28 | 28 |
#include "prof/prof.h" |
| ... | ... |
@@ -37,14 +37,14 @@ extern int emulating; |
| 37 | 37 |
int SWITicks = 0; |
| 38 | 38 |
int IRQTicks = 0; |
| 39 | 39 |
|
| 40 |
-u32 mastercode = 0; |
|
| 40 |
+uint32_t mastercode = 0; |
|
| 41 | 41 |
int layerEnableDelay = 0; |
| 42 | 42 |
bool busPrefetch = false; |
| 43 | 43 |
bool busPrefetchEnable = false; |
| 44 |
-u32 busPrefetchCount = 0; |
|
| 44 |
+uint32_t busPrefetchCount = 0; |
|
| 45 | 45 |
int cpuDmaTicksToUpdate = 0; |
| 46 | 46 |
int cpuDmaCount = 0; |
| 47 |
-u32 cpuDmaLast = 0; |
|
| 47 |
+uint32_t cpuDmaLast = 0; |
|
| 48 | 48 |
int dummyAddress = 0; |
| 49 | 49 |
|
| 50 | 50 |
bool cpuBreakLoop = false; |
| ... | ... |
@@ -60,7 +60,7 @@ bool cpuFlashEnabled = true; |
| 60 | 60 |
bool cpuEEPROMEnabled = true; |
| 61 | 61 |
bool cpuEEPROMSensorEnabled = false; |
| 62 | 62 |
|
| 63 |
-u32 cpuPrefetch[2]; |
|
| 63 |
+uint32_t cpuPrefetch[2]; |
|
| 64 | 64 |
|
| 65 | 65 |
int cpuTotalTicks = 0; |
| 66 | 66 |
#ifdef PROFILING |
| ... | ... |
@@ -70,51 +70,51 @@ static profile_segment *profilSegment = NULL; |
| 70 | 70 |
#endif |
| 71 | 71 |
|
| 72 | 72 |
#ifdef BKPT_SUPPORT |
| 73 |
-u8 freezeWorkRAM[0x40000]; |
|
| 74 |
-u8 freezeInternalRAM[0x8000]; |
|
| 75 |
-u8 freezeVRAM[0x18000]; |
|
| 76 |
-u8 freezePRAM[0x400]; |
|
| 77 |
-u8 freezeOAM[0x400]; |
|
| 73 |
+uint8_t freezeWorkRAM[0x40000]; |
|
| 74 |
+uint8_t freezeInternalRAM[0x8000]; |
|
| 75 |
+uint8_t freezeVRAM[0x18000]; |
|
| 76 |
+uint8_t freezePRAM[0x400]; |
|
| 77 |
+uint8_t freezeOAM[0x400]; |
|
| 78 | 78 |
bool debugger_last; |
| 79 | 79 |
#endif |
| 80 | 80 |
|
| 81 | 81 |
int lcdTicks = (useBios && !skipBios) ? 1008 : 208; |
| 82 |
-u8 timerOnOffDelay = 0; |
|
| 83 |
-u16 timer0Value = 0; |
|
| 82 |
+uint8_t timerOnOffDelay = 0; |
|
| 83 |
+uint16_t timer0Value = 0; |
|
| 84 | 84 |
bool timer0On = false; |
| 85 | 85 |
int timer0Ticks = 0; |
| 86 | 86 |
int timer0Reload = 0; |
| 87 | 87 |
int timer0ClockReload = 0; |
| 88 |
-u16 timer1Value = 0; |
|
| 88 |
+uint16_t timer1Value = 0; |
|
| 89 | 89 |
bool timer1On = false; |
| 90 | 90 |
int timer1Ticks = 0; |
| 91 | 91 |
int timer1Reload = 0; |
| 92 | 92 |
int timer1ClockReload = 0; |
| 93 |
-u16 timer2Value = 0; |
|
| 93 |
+uint16_t timer2Value = 0; |
|
| 94 | 94 |
bool timer2On = false; |
| 95 | 95 |
int timer2Ticks = 0; |
| 96 | 96 |
int timer2Reload = 0; |
| 97 | 97 |
int timer2ClockReload = 0; |
| 98 |
-u16 timer3Value = 0; |
|
| 98 |
+uint16_t timer3Value = 0; |
|
| 99 | 99 |
bool timer3On = false; |
| 100 | 100 |
int timer3Ticks = 0; |
| 101 | 101 |
int timer3Reload = 0; |
| 102 | 102 |
int timer3ClockReload = 0; |
| 103 |
-u32 dma0Source = 0; |
|
| 104 |
-u32 dma0Dest = 0; |
|
| 105 |
-u32 dma1Source = 0; |
|
| 106 |
-u32 dma1Dest = 0; |
|
| 107 |
-u32 dma2Source = 0; |
|
| 108 |
-u32 dma2Dest = 0; |
|
| 109 |
-u32 dma3Source = 0; |
|
| 110 |
-u32 dma3Dest = 0; |
|
| 103 |
+uint32_t dma0Source = 0; |
|
| 104 |
+uint32_t dma0Dest = 0; |
|
| 105 |
+uint32_t dma1Source = 0; |
|
| 106 |
+uint32_t dma1Dest = 0; |
|
| 107 |
+uint32_t dma2Source = 0; |
|
| 108 |
+uint32_t dma2Dest = 0; |
|
| 109 |
+uint32_t dma3Source = 0; |
|
| 110 |
+uint32_t dma3Dest = 0; |
|
| 111 | 111 |
//void (*cpuSaveGameFunc)(u32,u8) = /*flashSaveDecide*/0; |
| 112 | 112 |
//void (*renderLine)() = /*mode0RenderLine*/0; |
| 113 | 113 |
bool fxOn = false; |
| 114 | 114 |
bool windowOn = false; |
| 115 | 115 |
int frameCount = 0; |
| 116 | 116 |
char buffer[1024]; |
| 117 |
-u32 lastTime = 0; |
|
| 117 |
+uint32_t lastTime = 0; |
|
| 118 | 118 |
int count = 0; |
| 119 | 119 |
|
| 120 | 120 |
int capture = 0; |
| ... | ... |
@@ -128,23 +128,23 @@ const int TIMER_TICKS[4] = {
|
| 128 | 128 |
10 |
| 129 | 129 |
}; |
| 130 | 130 |
|
| 131 |
-const u32 objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
|
|
| 132 |
-const u8 gamepakRamWaitState[4] = { 4, 3, 2, 8 };
|
|
| 133 |
-const u8 gamepakWaitState[4] = { 4, 3, 2, 8 };
|
|
| 134 |
-const u8 gamepakWaitState0[2] = { 2, 1 };
|
|
| 135 |
-const u8 gamepakWaitState1[2] = { 4, 1 };
|
|
| 136 |
-const u8 gamepakWaitState2[2] = { 8, 1 };
|
|
| 131 |
+const uint32_t objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
|
|
| 132 |
+const uint8_t gamepakRamWaitState[4] = { 4, 3, 2, 8 };
|
|
| 133 |
+const uint8_t gamepakWaitState[4] = { 4, 3, 2, 8 };
|
|
| 134 |
+const uint8_t gamepakWaitState0[2] = { 2, 1 };
|
|
| 135 |
+const uint8_t gamepakWaitState1[2] = { 4, 1 };
|
|
| 136 |
+const uint8_t gamepakWaitState2[2] = { 8, 1 };
|
|
| 137 | 137 |
const bool isInRom [16]= |
| 138 | 138 |
{ false, false, false, false, false, false, false, false,
|
| 139 | 139 |
true, true, true, true, true, true, false, false }; |
| 140 | 140 |
|
| 141 |
-u8 memoryWait[16] = |
|
| 141 |
+uint8_t memoryWait[16] = |
|
| 142 | 142 |
{ 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
|
| 143 |
-u8 memoryWait32[16] = |
|
| 143 |
+uint8_t memoryWait32[16] = |
|
| 144 | 144 |
{ 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
|
| 145 |
-u8 memoryWaitSeq[16] = |
|
| 145 |
+uint8_t memoryWaitSeq[16] = |
|
| 146 | 146 |
{ 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
|
| 147 |
-u8 memoryWaitSeq32[16] = |
|
| 147 |
+uint8_t memoryWaitSeq32[16] = |
|
| 148 | 148 |
{ 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
|
| 149 | 149 |
|
| 150 | 150 |
// The videoMemoryWait constants are used to add some waitstates |
| ... | ... |
@@ -155,13 +155,13 @@ u8 memoryWaitSeq32[16] = |
| 155 | 155 |
// {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
| 156 | 156 |
|
| 157 | 157 |
|
| 158 |
-u8 biosProtected[4]; |
|
| 158 |
+uint8_t biosProtected[4]; |
|
| 159 | 159 |
|
| 160 | 160 |
#ifdef WORDS_BIGENDIAN |
| 161 | 161 |
bool cpuBiosSwapped = false; |
| 162 | 162 |
#endif |
| 163 | 163 |
|
| 164 |
-u32 myROM[] = {
|
|
| 164 |
+uint32_t myROM[] = {
|
|
| 165 | 165 |
0xEA000006, |
| 166 | 166 |
0xEA000093, |
| 167 | 167 |
0xEA000006, |
| ... | ... |
@@ -546,10 +546,10 @@ inline int CPUUpdateTicks() |
| 546 | 546 |
} |
| 547 | 547 |
}*/ |
| 548 | 548 |
|
| 549 |
-extern u32 line0[240]; |
|
| 550 |
-extern u32 line1[240]; |
|
| 551 |
-extern u32 line2[240]; |
|
| 552 |
-extern u32 line3[240]; |
|
| 549 |
+/*extern uint32_t line0[240]; |
|
| 550 |
+extern uint32_t line1[240]; |
|
| 551 |
+extern uint32_t line2[240]; |
|
| 552 |
+extern uint32_t line3[240]; |
|
| 553 | 553 |
|
| 554 | 554 |
#define CLEAR_ARRAY(a) \ |
| 555 | 555 |
{\
|
| ... | ... |
@@ -557,7 +557,7 @@ extern u32 line3[240]; |
| 557 | 557 |
for(int i = 0; i < 240; i++) {\
|
| 558 | 558 |
*array++ = 0x80000000;\ |
| 559 | 559 |
}\ |
| 560 |
- }\ |
|
| 560 |
+ }\*/ |
|
| 561 | 561 |
|
| 562 | 562 |
/*void CPUUpdateRenderBuffers(bool force) |
| 563 | 563 |
{
|
| ... | ... |
@@ -1339,13 +1339,13 @@ int CPULoadRom(const char *szFile) |
| 1339 | 1339 |
|
| 1340 | 1340 |
//systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
| 1341 | 1341 |
|
| 1342 |
- rom = (u8 *)malloc(0x2000000); |
|
| 1342 |
+ rom = (uint8_t *)malloc(0x2000000); |
|
| 1343 | 1343 |
if(rom == NULL) {
|
| 1344 | 1344 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1345 | 1345 |
"ROM");*/ |
| 1346 | 1346 |
return 0; |
| 1347 | 1347 |
} |
| 1348 |
- workRAM = (u8 *)calloc(1, 0x40000); |
|
| 1348 |
+ workRAM = (uint8_t *)calloc(1, 0x40000); |
|
| 1349 | 1349 |
if(workRAM == NULL) {
|
| 1350 | 1350 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1351 | 1351 |
"WRAM");*/ |
| ... | ... |
@@ -1395,56 +1395,56 @@ int CPULoadRom(const char *szFile) |
| 1395 | 1395 |
else |
| 1396 | 1396 |
mapgsf(rom, 0x2000000,romSize); |
| 1397 | 1397 |
|
| 1398 |
- u16 *temp = (u16 *)(rom+((romSize+1)&~1)); |
|
| 1398 |
+ uint16_t *temp = (uint16_t *)(rom+((romSize+1)&~1)); |
|
| 1399 | 1399 |
int i; |
| 1400 | 1400 |
for(i = (romSize+1)&~1; i < 0x2000000; i+=2) {
|
| 1401 | 1401 |
WRITE16LE(temp, (i >> 1) & 0xFFFF); |
| 1402 | 1402 |
temp++; |
| 1403 | 1403 |
} |
| 1404 | 1404 |
|
| 1405 |
- bios = (u8 *)calloc(1,0x4000); |
|
| 1405 |
+ bios = (uint8_t *)calloc(1,0x4000); |
|
| 1406 | 1406 |
if(bios == NULL) {
|
| 1407 | 1407 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1408 | 1408 |
"BIOS");*/ |
| 1409 | 1409 |
CPUCleanUp(); |
| 1410 | 1410 |
return 0; |
| 1411 | 1411 |
} |
| 1412 |
- internalRAM = (u8 *)calloc(1,0x8000); |
|
| 1412 |
+ internalRAM = (uint8_t *)calloc(1,0x8000); |
|
| 1413 | 1413 |
if(internalRAM == NULL) {
|
| 1414 | 1414 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1415 | 1415 |
"IRAM");*/ |
| 1416 | 1416 |
CPUCleanUp(); |
| 1417 | 1417 |
return 0; |
| 1418 | 1418 |
} |
| 1419 |
- paletteRAM = (u8 *)calloc(1,0x400); |
|
| 1419 |
+ paletteRAM = (uint8_t *)calloc(1,0x400); |
|
| 1420 | 1420 |
if(paletteRAM == NULL) {
|
| 1421 | 1421 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1422 | 1422 |
"PRAM");*/ |
| 1423 | 1423 |
CPUCleanUp(); |
| 1424 | 1424 |
return 0; |
| 1425 | 1425 |
} |
| 1426 |
- vram = (u8 *)calloc(1, 0x20000); |
|
| 1426 |
+ vram = (uint8_t *)calloc(1, 0x20000); |
|
| 1427 | 1427 |
if(vram == NULL) {
|
| 1428 | 1428 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1429 | 1429 |
"VRAM");*/ |
| 1430 | 1430 |
CPUCleanUp(); |
| 1431 | 1431 |
return 0; |
| 1432 | 1432 |
} |
| 1433 |
- oam = (u8 *)calloc(1, 0x400); |
|
| 1433 |
+ oam = (uint8_t *)calloc(1, 0x400); |
|
| 1434 | 1434 |
if(oam == NULL) {
|
| 1435 | 1435 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1436 | 1436 |
"OAM");*/ |
| 1437 | 1437 |
CPUCleanUp(); |
| 1438 | 1438 |
return 0; |
| 1439 | 1439 |
} |
| 1440 |
- pix = (u8 *)calloc(1, 4 * 241 * 162); |
|
| 1440 |
+ pix = (uint8_t *)calloc(1, 4 * 241 * 162); |
|
| 1441 | 1441 |
if(pix == NULL) {
|
| 1442 | 1442 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1443 | 1443 |
"PIX");*/ |
| 1444 | 1444 |
CPUCleanUp(); |
| 1445 | 1445 |
return 0; |
| 1446 | 1446 |
} |
| 1447 |
- ioMem = (u8 *)calloc(1, 0x400); |
|
| 1447 |
+ ioMem = (uint8_t *)calloc(1, 0x400); |
|
| 1448 | 1448 |
if(ioMem == NULL) {
|
| 1449 | 1449 |
/*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
| 1450 | 1450 |
"IO");*/ |
| ... | ... |
@@ -1462,8 +1462,8 @@ int CPULoadRom(const char *szFile) |
| 1462 | 1462 |
|
| 1463 | 1463 |
void doMirroring (bool b) |
| 1464 | 1464 |
{
|
| 1465 |
- u32 mirroredRomSize = (((romSize)>>20) & 0x3F)<<20; |
|
| 1466 |
- u32 mirroredRomAddress = romSize; |
|
| 1465 |
+ uint32_t mirroredRomSize = (((romSize)>>20) & 0x3F)<<20; |
|
| 1466 |
+ uint32_t mirroredRomAddress = romSize; |
|
| 1467 | 1467 |
if ((mirroredRomSize <=0x800000) && (b)) |
| 1468 | 1468 |
{
|
| 1469 | 1469 |
mirroredRomAddress = mirroredRomSize; |
| ... | ... |
@@ -1471,7 +1471,7 @@ void doMirroring (bool b) |
| 1471 | 1471 |
mirroredRomSize=0x100000; |
| 1472 | 1472 |
while (mirroredRomAddress<0x01000000) |
| 1473 | 1473 |
{
|
| 1474 |
- memcpy ((u16 *)(rom+mirroredRomAddress), (u16 *)(rom), mirroredRomSize); |
|
| 1474 |
+ memcpy ((uint16_t *)(rom+mirroredRomAddress), (uint16_t *)(rom), mirroredRomSize); |
|
| 1475 | 1475 |
mirroredRomAddress+=mirroredRomSize; |
| 1476 | 1476 |
} |
| 1477 | 1477 |
} |
| ... | ... |
@@ -1540,7 +1540,7 @@ void doMirroring (bool b) |
| 1540 | 1540 |
|
| 1541 | 1541 |
void CPUUpdateCPSR() |
| 1542 | 1542 |
{
|
| 1543 |
- u32 CPSR = reg[16].I & 0x40; |
|
| 1543 |
+ uint32_t CPSR = reg[16].I & 0x40; |
|
| 1544 | 1544 |
if(N_FLAG) |
| 1545 | 1545 |
CPSR |= 0x80000000; |
| 1546 | 1546 |
if(Z_FLAG) |
| ... | ... |
@@ -1559,7 +1559,7 @@ void CPUUpdateCPSR() |
| 1559 | 1559 |
|
| 1560 | 1560 |
void CPUUpdateFlags(bool breakLoop) |
| 1561 | 1561 |
{
|
| 1562 |
- u32 CPSR = reg[16].I; |
|
| 1562 |
+ uint32_t CPSR = reg[16].I; |
|
| 1563 | 1563 |
|
| 1564 | 1564 |
N_FLAG = (CPSR & 0x80000000) ? true: false; |
| 1565 | 1565 |
Z_FLAG = (CPSR & 0x40000000) ? true: false; |
| ... | ... |
@@ -1579,16 +1579,16 @@ void CPUUpdateFlags() |
| 1579 | 1579 |
} |
| 1580 | 1580 |
|
| 1581 | 1581 |
#ifdef WORDS_BIGENDIAN |
| 1582 |
-static void CPUSwap(volatile u32 *a, volatile u32 *b) |
|
| 1582 |
+static void CPUSwap(volatile uint32_t *a, volatile uint32_t *b) |
|
| 1583 | 1583 |
{
|
| 1584 |
- volatile u32 c = *b; |
|
| 1584 |
+ volatile uint32_t c = *b; |
|
| 1585 | 1585 |
*b = *a; |
| 1586 | 1586 |
*a = c; |
| 1587 | 1587 |
} |
| 1588 | 1588 |
#else |
| 1589 |
-static void CPUSwap(u32 *a, u32 *b) |
|
| 1589 |
+static void CPUSwap(uint32_t *a, uint32_t *b) |
|
| 1590 | 1590 |
{
|
| 1591 |
- u32 c = *b; |
|
| 1591 |
+ uint32_t c = *b; |
|
| 1592 | 1592 |
*b = *a; |
| 1593 | 1593 |
*a = c; |
| 1594 | 1594 |
} |
| ... | ... |
@@ -1640,8 +1640,8 @@ void CPUSwitchMode(int mode, bool saveState, bool breakLoop) |
| 1640 | 1640 |
break; |
| 1641 | 1641 |
} |
| 1642 | 1642 |
|
| 1643 |
- u32 CPSR = reg[16].I; |
|
| 1644 |
- u32 SPSR = reg[17].I; |
|
| 1643 |
+ uint32_t CPSR = reg[16].I; |
|
| 1644 |
+ uint32_t SPSR = reg[17].I; |
|
| 1645 | 1645 |
|
| 1646 | 1646 |
switch(mode) {
|
| 1647 | 1647 |
case 0x10: |
| ... | ... |
@@ -1715,7 +1715,7 @@ void CPUSwitchMode(int mode, bool saveState) |
| 1715 | 1715 |
|
| 1716 | 1716 |
void CPUUndefinedException() |
| 1717 | 1717 |
{
|
| 1718 |
- u32 PC = reg[15].I; |
|
| 1718 |
+ uint32_t PC = reg[15].I; |
|
| 1719 | 1719 |
bool savedArmState = armState; |
| 1720 | 1720 |
CPUSwitchMode(0x1b, true, false); |
| 1721 | 1721 |
reg[14].I = PC - (savedArmState ? 4 : 2); |
| ... | ... |
@@ -1729,7 +1729,7 @@ void CPUUndefinedException() |
| 1729 | 1729 |
|
| 1730 | 1730 |
void CPUSoftwareInterrupt() |
| 1731 | 1731 |
{
|
| 1732 |
- u32 PC = reg[15].I; |
|
| 1732 |
+ uint32_t PC = reg[15].I; |
|
| 1733 | 1733 |
bool savedArmState = armState; |
| 1734 | 1734 |
CPUSwitchMode(0x13, true, false); |
| 1735 | 1735 |
reg[14].I = PC - (savedArmState ? 4 : 2); |
| ... | ... |
@@ -1930,7 +1930,7 @@ void CPUSoftwareInterrupt(int comment) |
| 1930 | 1930 |
break; |
| 1931 | 1931 |
case 0x11: |
| 1932 | 1932 |
{
|
| 1933 |
- u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1933 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1934 | 1934 |
if(!(((reg[0].I & 0xe000000) == 0) || |
| 1935 | 1935 |
((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
| 1936 | 1936 |
SWITicks = (9 + memoryWait[(reg[1].I>>24) & 0xF]) * len; |
| ... | ... |
@@ -1939,7 +1939,7 @@ void CPUSoftwareInterrupt(int comment) |
| 1939 | 1939 |
break; |
| 1940 | 1940 |
case 0x12: |
| 1941 | 1941 |
{
|
| 1942 |
- u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1942 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1943 | 1943 |
if(!(((reg[0].I & 0xe000000) == 0) || |
| 1944 | 1944 |
((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
| 1945 | 1945 |
SWITicks = (19 + memoryWait[(reg[1].I>>24) & 0xF]) * len; |
| ... | ... |
@@ -1948,7 +1948,7 @@ void CPUSoftwareInterrupt(int comment) |
| 1948 | 1948 |
break; |
| 1949 | 1949 |
case 0x13: |
| 1950 | 1950 |
{
|
| 1951 |
- u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1951 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1952 | 1952 |
if(!(((reg[0].I & 0xe000000) == 0) || |
| 1953 | 1953 |
((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
| 1954 | 1954 |
SWITicks = (29 + (memoryWait[(reg[0].I>>24) & 0xF]<<1)) * len; |
| ... | ... |
@@ -1957,7 +1957,7 @@ void CPUSoftwareInterrupt(int comment) |
| 1957 | 1957 |
break; |
| 1958 | 1958 |
case 0x14: |
| 1959 | 1959 |
{
|
| 1960 |
- u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1960 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1961 | 1961 |
if(!(((reg[0].I & 0xe000000) == 0) || |
| 1962 | 1962 |
((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
| 1963 | 1963 |
SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] + |
| ... | ... |
@@ -1967,7 +1967,7 @@ void CPUSoftwareInterrupt(int comment) |
| 1967 | 1967 |
break; |
| 1968 | 1968 |
case 0x15: |
| 1969 | 1969 |
{
|
| 1970 |
- u32 len = CPUReadMemory(reg[0].I) >> 9; |
|
| 1970 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 1971 | 1971 |
if(!(((reg[0].I & 0xe000000) == 0) || |
| 1972 | 1972 |
((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
| 1973 | 1973 |
SWITicks = (34 + (memoryWait[(reg[0].I>>24) & 0xF] << 1) + |
| ... | ... |
@@ -1977,7 +1977,7 @@ void CPUSoftwareInterrupt(int comment) |
| 1977 | 1977 |
break; |
| 1978 | 1978 |
case 0x16: |
| 1979 | 1979 |
{
|
| 1980 |
- u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1980 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1981 | 1981 |
if(!(((reg[0].I & 0xe000000) == 0) || |
| 1982 | 1982 |
((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
| 1983 | 1983 |
SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] + |
| ... | ... |
@@ -1987,7 +1987,7 @@ void CPUSoftwareInterrupt(int comment) |
| 1987 | 1987 |
break; |
| 1988 | 1988 |
case 0x17: |
| 1989 | 1989 |
{
|
| 1990 |
- u32 len = CPUReadMemory(reg[0].I) >> 9; |
|
| 1990 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 1991 | 1991 |
if(!(((reg[0].I & 0xe000000) == 0) || |
| 1992 | 1992 |
((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
| 1993 | 1993 |
SWITicks = (39 + (memoryWait[(reg[0].I>>24) & 0xF]<<1) + |
| ... | ... |
@@ -1997,7 +1997,7 @@ void CPUSoftwareInterrupt(int comment) |
| 1997 | 1997 |
break; |
| 1998 | 1998 |
case 0x18: |
| 1999 | 1999 |
{
|
| 2000 |
- u32 len = CPUReadMemory(reg[0].I) >> 9; |
|
| 2000 |
+ uint32_t len = CPUReadMemory(reg[0].I) >> 9; |
|
| 2001 | 2001 |
if(!(((reg[0].I & 0xe000000) == 0) || |
| 2002 | 2002 |
((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
| 2003 | 2003 |
SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] + |
| ... | ... |
@@ -2070,7 +2070,7 @@ void CPUCompareVCOUNT() |
| 2070 | 2070 |
|
| 2071 | 2071 |
} |
| 2072 | 2072 |
|
| 2073 |
-void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32) |
|
| 2073 |
+void doDMA(uint32_t &s, uint32_t &d, uint32_t si, uint32_t di, uint32_t c, int transfer32) |
|
| 2074 | 2074 |
{
|
| 2075 | 2075 |
int sm = s >> 24; |
| 2076 | 2076 |
int dm = d >> 24; |
| ... | ... |
@@ -2154,13 +2154,13 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2154 | 2154 |
// DMA 0 |
| 2155 | 2155 |
if((DM0CNT_H & 0x8000) && (dmamask & 1)) {
|
| 2156 | 2156 |
if(((DM0CNT_H >> 12) & 3) == reason) {
|
| 2157 |
- u32 sourceIncrement = 4; |
|
| 2158 |
- u32 destIncrement = 4; |
|
| 2157 |
+ uint32_t sourceIncrement = 4; |
|
| 2158 |
+ uint32_t destIncrement = 4; |
|
| 2159 | 2159 |
switch((DM0CNT_H >> 7) & 3) {
|
| 2160 | 2160 |
case 0: |
| 2161 | 2161 |
break; |
| 2162 | 2162 |
case 1: |
| 2163 |
- sourceIncrement = (u32)-4; |
|
| 2163 |
+ sourceIncrement = (uint32_t)-4; |
|
| 2164 | 2164 |
break; |
| 2165 | 2165 |
case 2: |
| 2166 | 2166 |
sourceIncrement = 0; |
| ... | ... |
@@ -2170,7 +2170,7 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2170 | 2170 |
case 0: |
| 2171 | 2171 |
break; |
| 2172 | 2172 |
case 1: |
| 2173 |
- destIncrement = (u32)-4; |
|
| 2173 |
+ destIncrement = (uint32_t)-4; |
|
| 2174 | 2174 |
break; |
| 2175 | 2175 |
case 2: |
| 2176 | 2176 |
destIncrement = 0; |
| ... | ... |
@@ -2210,13 +2210,13 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2210 | 2210 |
// DMA 1 |
| 2211 | 2211 |
if((DM1CNT_H & 0x8000) && (dmamask & 2)) {
|
| 2212 | 2212 |
if(((DM1CNT_H >> 12) & 3) == reason) {
|
| 2213 |
- u32 sourceIncrement = 4; |
|
| 2214 |
- u32 destIncrement = 4; |
|
| 2213 |
+ uint32_t sourceIncrement = 4; |
|
| 2214 |
+ uint32_t destIncrement = 4; |
|
| 2215 | 2215 |
switch((DM1CNT_H >> 7) & 3) {
|
| 2216 | 2216 |
case 0: |
| 2217 | 2217 |
break; |
| 2218 | 2218 |
case 1: |
| 2219 |
- sourceIncrement = (u32)-4; |
|
| 2219 |
+ sourceIncrement = (uint32_t)-4; |
|
| 2220 | 2220 |
break; |
| 2221 | 2221 |
case 2: |
| 2222 | 2222 |
sourceIncrement = 0; |
| ... | ... |
@@ -2226,7 +2226,7 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2226 | 2226 |
case 0: |
| 2227 | 2227 |
break; |
| 2228 | 2228 |
case 1: |
| 2229 |
- destIncrement = (u32)-4; |
|
| 2229 |
+ destIncrement = (uint32_t)-4; |
|
| 2230 | 2230 |
break; |
| 2231 | 2231 |
case 2: |
| 2232 | 2232 |
destIncrement = 0; |
| ... | ... |
@@ -2278,13 +2278,13 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2278 | 2278 |
// DMA 2 |
| 2279 | 2279 |
if((DM2CNT_H & 0x8000) && (dmamask & 4)) {
|
| 2280 | 2280 |
if(((DM2CNT_H >> 12) & 3) == reason) {
|
| 2281 |
- u32 sourceIncrement = 4; |
|
| 2282 |
- u32 destIncrement = 4; |
|
| 2281 |
+ uint32_t sourceIncrement = 4; |
|
| 2282 |
+ uint32_t destIncrement = 4; |
|
| 2283 | 2283 |
switch((DM2CNT_H >> 7) & 3) {
|
| 2284 | 2284 |
case 0: |
| 2285 | 2285 |
break; |
| 2286 | 2286 |
case 1: |
| 2287 |
- sourceIncrement = (u32)-4; |
|
| 2287 |
+ sourceIncrement = (uint32_t)-4; |
|
| 2288 | 2288 |
break; |
| 2289 | 2289 |
case 2: |
| 2290 | 2290 |
sourceIncrement = 0; |
| ... | ... |
@@ -2294,7 +2294,7 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2294 | 2294 |
case 0: |
| 2295 | 2295 |
break; |
| 2296 | 2296 |
case 1: |
| 2297 |
- destIncrement = (u32)-4; |
|
| 2297 |
+ destIncrement = (uint32_t)-4; |
|
| 2298 | 2298 |
break; |
| 2299 | 2299 |
case 2: |
| 2300 | 2300 |
destIncrement = 0; |
| ... | ... |
@@ -2347,13 +2347,13 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2347 | 2347 |
// DMA 3 |
| 2348 | 2348 |
if((DM3CNT_H & 0x8000) && (dmamask & 8)) {
|
| 2349 | 2349 |
if(((DM3CNT_H >> 12) & 3) == reason) {
|
| 2350 |
- u32 sourceIncrement = 4; |
|
| 2351 |
- u32 destIncrement = 4; |
|
| 2350 |
+ uint32_t sourceIncrement = 4; |
|
| 2351 |
+ uint32_t destIncrement = 4; |
|
| 2352 | 2352 |
switch((DM3CNT_H >> 7) & 3) {
|
| 2353 | 2353 |
case 0: |
| 2354 | 2354 |
break; |
| 2355 | 2355 |
case 1: |
| 2356 |
- sourceIncrement = (u32)-4; |
|
| 2356 |
+ sourceIncrement = (uint32_t)-4; |
|
| 2357 | 2357 |
break; |
| 2358 | 2358 |
case 2: |
| 2359 | 2359 |
sourceIncrement = 0; |
| ... | ... |
@@ -2363,7 +2363,7 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2363 | 2363 |
case 0: |
| 2364 | 2364 |
break; |
| 2365 | 2365 |
case 1: |
| 2366 |
- destIncrement = (u32)-4; |
|
| 2366 |
+ destIncrement = (uint32_t)-4; |
|
| 2367 | 2367 |
break; |
| 2368 | 2368 |
case 2: |
| 2369 | 2369 |
destIncrement = 0; |
| ... | ... |
@@ -2400,7 +2400,7 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2400 | 2400 |
} |
| 2401 | 2401 |
} |
| 2402 | 2402 |
|
| 2403 |
-void CPUUpdateRegister(u32 address, u16 value) |
|
| 2403 |
+void CPUUpdateRegister(uint32_t address, uint16_t value) |
|
| 2404 | 2404 |
{
|
| 2405 | 2405 |
switch(address) |
| 2406 | 2406 |
{
|
| ... | ... |
@@ -2412,7 +2412,7 @@ void CPUUpdateRegister(u32 address, u16 value) |
| 2412 | 2412 |
} |
| 2413 | 2413 |
bool change = (0 != ((DISPCNT ^ value) & 0x80)); |
| 2414 | 2414 |
bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00)); |
| 2415 |
- u16 changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated |
|
| 2415 |
+ uint16_t changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated |
|
| 2416 | 2416 |
|
| 2417 | 2417 |
DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode |
| 2418 | 2418 |
UPDATE_REG(0x00, DISPCNT); |
| ... | ... |
@@ -2627,8 +2627,8 @@ void CPUUpdateRegister(u32 address, u16 value) |
| 2627 | 2627 |
case 0x7c: |
| 2628 | 2628 |
case 0x80: |
| 2629 | 2629 |
case 0x84: |
| 2630 |
- soundEvent(address&0xFF, (u8)(value & 0xFF)); |
|
| 2631 |
- soundEvent((address&0xFF)+1, (u8)(value>>8)); |
|
| 2630 |
+ soundEvent(address&0xFF, (uint8_t)(value & 0xFF)); |
|
| 2631 |
+ soundEvent((address&0xFF)+1, (uint8_t)(value>>8)); |
|
| 2632 | 2632 |
break; |
| 2633 | 2633 |
case 0x82: |
| 2634 | 2634 |
case 0x88: |
| ... | ... |
@@ -3013,8 +3013,8 @@ void applyTimer () |
| 3013 | 3013 |
timerOnOffDelay = 0; |
| 3014 | 3014 |
} |
| 3015 | 3015 |
|
| 3016 |
-u8 cpuBitsSet[256]; |
|
| 3017 |
-u8 cpuLowestBitSet[256]; |
|
| 3016 |
+uint8_t cpuBitsSet[256]; |
|
| 3017 |
+uint8_t cpuLowestBitSet[256]; |
|
| 3018 | 3018 |
|
| 3019 | 3019 |
void CPUInit(const char *biosFileName, bool useBiosFile) |
| 3020 | 3020 |
{
|
| ... | ... |
@@ -3105,8 +3105,8 @@ void CPUInit(const char *biosFileName, bool useBiosFile) |
| 3105 | 3105 |
ioReadable[i] = false; |
| 3106 | 3106 |
|
| 3107 | 3107 |
if(romSize < 0x1fe2000) {
|
| 3108 |
- *((u16 *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA |
|
| 3109 |
- *((u16 *)&rom[0x1fe209e]) = 0x4770; // BX LR |
|
| 3108 |
+ *((uint16_t *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA |
|
| 3109 |
+ *((uint16_t *)&rom[0x1fe209e]) = 0x4770; // BX LR |
|
| 3110 | 3110 |
} else {
|
| 3111 | 3111 |
//agbPrintEnable(false); |
| 3112 | 3112 |
} |
| ... | ... |
@@ -3306,7 +3306,7 @@ void CPUReset() |
| 3306 | 3306 |
//CPUUpdateRenderBuffers(true); |
| 3307 | 3307 |
|
| 3308 | 3308 |
for(int i = 0; i < 256; i++) {
|
| 3309 |
- map[i].address = (u8 *)&dummyAddress; |
|
| 3309 |
+ map[i].address = (uint8_t *)&dummyAddress; |
|
| 3310 | 3310 |
map[i].mask = 0; |
| 3311 | 3311 |
} |
| 3312 | 3312 |
|
| ... | ... |
@@ -3415,7 +3415,7 @@ void CPUReset() |
| 3415 | 3415 |
|
| 3416 | 3416 |
void CPUInterrupt() |
| 3417 | 3417 |
{
|
| 3418 |
- u32 PC = reg[15].I; |
|
| 3418 |
+ uint32_t PC = reg[15].I; |
|
| 3419 | 3419 |
bool savedState = armState; |
| 3420 | 3420 |
CPUSwitchMode(0x12, true, false); |
| 3421 | 3421 |
reg[14].I = PC; |
| ... | ... |
@@ -3547,9 +3547,9 @@ void CPULoop(int ticks) |
| 3547 | 3547 |
CPUCompareVCOUNT(); |
| 3548 | 3548 |
} |
| 3549 | 3549 |
} else {
|
| 3550 |
- int framesToSkip = /*systemFrameSkip*/0; |
|
| 3550 |
+ /*int framesToSkip = *//*systemFrameSkip*//*0; |
|
| 3551 | 3551 |
if(speedup) |
| 3552 |
- framesToSkip = 9; // try 6 FPS during speedup |
|
| 3552 |
+ framesToSkip = 9;*/ // try 6 FPS during speedup |
|
| 3553 | 3553 |
|
| 3554 | 3554 |
if(DISPSTAT & 2) {
|
| 3555 | 3555 |
// if in H-Blank, leave it and move to drawing mode |
| ... | ... |
@@ -3562,28 +3562,28 @@ void CPULoop(int ticks) |
| 3562 | 3562 |
count++; |
| 3563 | 3563 |
//systemFrame(); |
| 3564 | 3564 |
|
| 3565 |
- if((count % 10) == 0) {
|
|
| 3565 |
+ /*if((count % 10) == 0) {
|
|
| 3566 | 3566 |
//system10Frames(60); |
| 3567 |
- } |
|
| 3567 |
+ }*/ |
|
| 3568 | 3568 |
if(count == 60) {
|
| 3569 |
- u32 time = /*systemGetClock()*/0; |
|
| 3569 |
+ /*u32 time = *//*systemGetClock()*//*0; |
|
| 3570 | 3570 |
if(time != lastTime) {
|
| 3571 | 3571 |
//u32 t = 100000/(time - lastTime); |
| 3572 | 3572 |
//systemShowSpeed(t); |
| 3573 | 3573 |
} else |
| 3574 | 3574 |
//systemShowSpeed(0); |
| 3575 |
- lastTime = time; |
|
| 3575 |
+ lastTime = time;*/ |
|
| 3576 | 3576 |
count = 0; |
| 3577 | 3577 |
} |
| 3578 |
- u32 joy = 0; |
|
| 3578 |
+ //u32 joy = 0; |
|
| 3579 | 3579 |
// update joystick information |
| 3580 | 3580 |
/*if(systemReadJoypads()) |
| 3581 | 3581 |
// read default joystick |
| 3582 | 3582 |
joy = systemReadJoypad(-1);*/ |
| 3583 |
- P1 = 0x03FF ^ (joy & 0x3FF); |
|
| 3583 |
+ //P1 = 0x03FF ^ (joy & 0x3FF); |
|
| 3584 | 3584 |
/*if(cpuEEPROMSensorEnabled) |
| 3585 | 3585 |
systemUpdateMotionSensor();*/ |
| 3586 |
- UPDATE_REG(0x130, P1); |
|
| 3586 |
+ /*UPDATE_REG(0x130, P1); |
|
| 3587 | 3587 |
u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132])); |
| 3588 | 3588 |
// this seems wrong, but there are cases where the game |
| 3589 | 3589 |
// can enter the stop state without requesting an IRQ from |
| ... | ... |
@@ -3603,18 +3603,18 @@ void CPULoop(int ticks) |
| 3603 | 3603 |
} |
| 3604 | 3604 |
} |
| 3605 | 3605 |
|
| 3606 |
- u32 ext = (joy >> 10); |
|
| 3606 |
+ u32 ext = (joy >> 10);*/ |
|
| 3607 | 3607 |
// If no (m) code is enabled, apply the cheats at each LCDline |
| 3608 | 3608 |
/*if((cheatsEnabled) && (mastercode==0)) |
| 3609 | 3609 |
remainingTicks += cheatsCheckKeys(P1^0x3FF, ext);*/ |
| 3610 |
- speedup = (ext & 1) ? true : false; |
|
| 3610 |
+ /*speedup = (ext & 1) ? true : false; |
|
| 3611 | 3611 |
capture = (ext & 2) ? true : false; |
| 3612 | 3612 |
|
| 3613 | 3613 |
if(capture && !capturePrevious) {
|
| 3614 | 3614 |
captureNumber++; |
| 3615 | 3615 |
//systemScreenCapture(captureNumber); |
| 3616 | 3616 |
} |
| 3617 |
- capturePrevious = capture; |
|
| 3617 |
+ capturePrevious = capture;*/ |
|
| 3618 | 3618 |
|
| 3619 | 3619 |
DISPSTAT |= 1; |
| 3620 | 3620 |
DISPSTAT &= 0xFFFD; |
| ... | ... |
@@ -3624,10 +3624,10 @@ void CPULoop(int ticks) |
| 3624 | 3624 |
UPDATE_REG(0x202, IF); |
| 3625 | 3625 |
} |
| 3626 | 3626 |
CPUCheckDMA(1, 0x0f); |
| 3627 |
- if(frameCount >= framesToSkip) {
|
|
| 3627 |
+ /*if(frameCount >= framesToSkip) {
|
|
| 3628 | 3628 |
//systemDrawScreen(); |
| 3629 | 3629 |
frameCount = 0; |
| 3630 |
- } else |
|
| 3630 |
+ } else*/ |
|
| 3631 | 3631 |
frameCount++; |
| 3632 | 3632 |
/*if(systemPauseOnFrame()) |
| 3633 | 3633 |
ticks = 0;*/ |
| ... | ... |
@@ -3637,8 +3637,8 @@ void CPULoop(int ticks) |
| 3637 | 3637 |
CPUCompareVCOUNT(); |
| 3638 | 3638 |
|
| 3639 | 3639 |
} else {
|
| 3640 |
- if(frameCount >= framesToSkip) |
|
| 3641 |
- {
|
|
| 3640 |
+ /*if(frameCount >= framesToSkip) |
|
| 3641 |
+ {*/
|
|
| 3642 | 3642 |
/*(*renderLine)(); |
| 3643 | 3643 |
switch(systemColorDepth) {
|
| 3644 | 3644 |
case 16: |
| ... | ... |
@@ -3738,7 +3738,7 @@ void CPULoop(int ticks) |
| 3738 | 3738 |
} |
| 3739 | 3739 |
break; |
| 3740 | 3740 |
}*/ |
| 3741 |
- } |
|
| 3741 |
+ /*}*/ |
|
| 3742 | 3742 |
// entering H-Blank |
| 3743 | 3743 |
DISPSTAT |= 2; |
| 3744 | 3744 |
UPDATE_REG(0x04, DISPSTAT); |
| ... | ... |
@@ -3876,7 +3876,7 @@ void CPULoop(int ticks) |
| 3876 | 3876 |
if(profilSegment) {
|
| 3877 | 3877 |
profile_segment *seg = profilSegment; |
| 3878 | 3878 |
do {
|
| 3879 |
- u16 *b = (u16 *)seg->sbuf; |
|
| 3879 |
+ uint16_t *b = (uint16_t *)seg->sbuf; |
|
| 3880 | 3880 |
int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale)/0x10000; |
| 3881 | 3881 |
if(pc >= 0 && pc < seg->ssiz) {
|
| 3882 | 3882 |
b[pc]++; |
| ... | ... |
@@ -1826,10 +1826,10 @@ void CPUSoftwareInterrupt(int comment) |
| 1826 | 1826 |
VCOUNT);*/ |
| 1827 | 1827 |
} |
| 1828 | 1828 |
#endif |
| 1829 |
- holdState = true; |
|
| 1829 |
+ /*holdState = true; |
|
| 1830 | 1830 |
holdType = -1; |
| 1831 | 1831 |
stopState = true; |
| 1832 |
- cpuNextEvent = cpuTotalTicks; |
|
| 1832 |
+ cpuNextEvent = cpuTotalTicks;*/ |
|
| 1833 | 1833 |
break; |
| 1834 | 1834 |
case 0x04: |
| 1835 | 1835 |
#ifdef GBA_LOGGING |
| ... | ... |
@@ -44,7 +44,6 @@ bool busPrefetchEnable = false; |
| 44 | 44 |
u32 busPrefetchCount = 0; |
| 45 | 45 |
int cpuDmaTicksToUpdate = 0; |
| 46 | 46 |
int cpuDmaCount = 0; |
| 47 |
-bool cpuDmaHack = false; |
|
| 48 | 47 |
u32 cpuDmaLast = 0; |
| 49 | 48 |
int dummyAddress = 0; |
| 50 | 49 |
|
| ... | ... |
@@ -936,7 +935,7 @@ bool CPUReadGSASnapshot(const char *fileName) |
| 936 | 935 |
fseek(file, 0x0, SEEK_SET); |
| 937 | 936 |
fread(&i, 1, 4, file); |
| 938 | 937 |
fseek(file, i, SEEK_CUR); // Skip SharkPortSave |
| 939 |
- fseek(file, 4, SEEK_CUR); // skip some sort of flag |
|
| 938 |
+// fseek(file, 4, SEEK_CUR); // skip some sort of flag |
|
| 940 | 939 |
fread(&i, 1, 4, file); // name length |
| 941 | 940 |
fseek(file, i, SEEK_CUR); // skip name |
| 942 | 941 |
fread(&i, 1, 4, file); // desc length |
| ... | ... |
@@ -1812,8 +1811,8 @@ void CPUSoftwareInterrupt(int comment) |
| 1812 | 1811 |
case 0x02: |
| 1813 | 1812 |
#ifdef GBA_LOGGING |
| 1814 | 1813 |
if(systemVerbose & VERBOSE_SWI) {
|
| 1815 |
- log("Halt: (VCOUNT = %2d)\n",
|
|
| 1816 |
- VCOUNT); |
|
| 1814 |
+ /*log("Halt: (VCOUNT = %2d)\n",
|
|
| 1815 |
+ VCOUNT);*/ |
|
| 1817 | 1816 |
} |
| 1818 | 1817 |
#endif |
| 1819 | 1818 |
holdState = true; |
| ... | ... |
@@ -1823,8 +1822,8 @@ void CPUSoftwareInterrupt(int comment) |
| 1823 | 1822 |
case 0x03: |
| 1824 | 1823 |
#ifdef GBA_LOGGING |
| 1825 | 1824 |
if(systemVerbose & VERBOSE_SWI) {
|
| 1826 |
- log("Stop: (VCOUNT = %2d)\n",
|
|
| 1827 |
- VCOUNT); |
|
| 1825 |
+ /*log("Stop: (VCOUNT = %2d)\n",
|
|
| 1826 |
+ VCOUNT);*/ |
|
| 1828 | 1827 |
} |
| 1829 | 1828 |
#endif |
| 1830 | 1829 |
holdState = true; |
| ... | ... |
@@ -2190,7 +2189,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2190 | 2189 |
doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, |
| 2191 | 2190 |
DM0CNT_L ? DM0CNT_L : 0x4000, |
| 2192 | 2191 |
DM0CNT_H & 0x0400); |
| 2193 |
- cpuDmaHack = true; |
|
| 2194 | 2192 |
|
| 2195 | 2193 |
if(DM0CNT_H & 0x4000) {
|
| 2196 | 2194 |
IF |= 0x0100; |
| ... | ... |
@@ -2259,7 +2257,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2259 | 2257 |
DM1CNT_L ? DM1CNT_L : 0x4000, |
| 2260 | 2258 |
DM1CNT_H & 0x0400); |
| 2261 | 2259 |
} |
| 2262 |
- cpuDmaHack = true; |
|
| 2263 | 2260 |
|
| 2264 | 2261 |
if(DM1CNT_H & 0x4000) {
|
| 2265 | 2262 |
IF |= 0x0200; |
| ... | ... |
@@ -2329,7 +2326,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2329 | 2326 |
DM2CNT_L ? DM2CNT_L : 0x4000, |
| 2330 | 2327 |
DM2CNT_H & 0x0400); |
| 2331 | 2328 |
} |
| 2332 |
- cpuDmaHack = true; |
|
| 2333 | 2329 |
|
| 2334 | 2330 |
if(DM2CNT_H & 0x4000) {
|
| 2335 | 2331 |
IF |= 0x0400; |
| ... | ... |
@@ -3412,8 +3408,6 @@ void CPUReset() |
| 3412 | 3408 |
|
| 3413 | 3409 |
//systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
| 3414 | 3410 |
|
| 3415 |
- cpuDmaHack = false; |
|
| 3416 |
- |
|
| 3417 | 3411 |
lastTime = /*systemGetClock()*/0; |
| 3418 | 3412 |
|
| 3419 | 3413 |
SWITicks = 0; |
| ... | ... |
@@ -3512,7 +3506,6 @@ void CPULoop(int ticks) |
| 3512 | 3506 |
|
| 3513 | 3507 |
clockTicks = cpuNextEvent; |
| 3514 | 3508 |
cpuTotalTicks = 0; |
| 3515 |
- cpuDmaHack = false; |
|
| 3516 | 3509 |
|
| 3517 | 3510 |
updateLoop: |
| 3518 | 3511 |
|
| ... | ... |
@@ -3914,7 +3907,6 @@ void CPULoop(int ticks) |
| 3914 | 3907 |
cpuDmaTicksToUpdate -= clockTicks; |
| 3915 | 3908 |
if(cpuDmaTicksToUpdate < 0) |
| 3916 | 3909 |
cpuDmaTicksToUpdate = 0; |
| 3917 |
- cpuDmaHack = true; |
|
| 3918 | 3910 |
goto updateLoop; |
| 3919 | 3911 |
} |
| 3920 | 3912 |
|
| ... | ... |
@@ -1353,7 +1353,7 @@ int CPULoadRom(const char *szFile) |
| 1353 | 1353 |
return 0; |
| 1354 | 1354 |
} |
| 1355 | 1355 |
|
| 1356 |
- u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom; |
|
| 1356 |
+ //u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom; |
|
| 1357 | 1357 |
|
| 1358 | 1358 |
#ifndef NO_DEBUGGER |
| 1359 | 1359 |
if(CPUIsELF(szFile)) {
|
| ... | ... |
@@ -3575,7 +3575,7 @@ void CPULoop(int ticks) |
| 3575 | 3575 |
if(count == 60) {
|
| 3576 | 3576 |
u32 time = /*systemGetClock()*/0; |
| 3577 | 3577 |
if(time != lastTime) {
|
| 3578 |
- u32 t = 100000/(time - lastTime); |
|
| 3578 |
+ //u32 t = 100000/(time - lastTime); |
|
| 3579 | 3579 |
//systemShowSpeed(t); |
| 3580 | 3580 |
} else |
| 3581 | 3581 |
//systemShowSpeed(0); |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,4025 @@ |
| 1 |
+#include <stdio.h> |
|
| 2 |
+#include <stdlib.h> |
|
| 3 |
+#include <memory.h> |
|
| 4 |
+#include <stdarg.h> |
|
| 5 |
+#include <string.h> |
|
| 6 |
+#include "GBA.h" |
|
| 7 |
+#include "GBAcpu.h" |
|
| 8 |
+#include "GBAinline.h" |
|
| 9 |
+#include "Globals.h" |
|
| 10 |
+//#include "GBAGfx.h" |
|
| 11 |
+//#include "EEprom.h" |
|
| 12 |
+//#include "Flash.h" |
|
| 13 |
+#include "Sound.h" |
|
| 14 |
+//#include "Sram.h" |
|
| 15 |
+#include "bios.h" |
|
| 16 |
+//#include "Cheats.h" |
|
| 17 |
+//#include "../NLS.h" |
|
| 18 |
+//#include "elf.h" |
|
| 19 |
+//#include "../Util.h" |
|
| 20 |
+#include "../common/Port.h" |
|
| 21 |
+//#include "../System.h" |
|
| 22 |
+//#include "agbprint.h" |
|
| 23 |
+//#include "GBALink.h" |
|
| 24 |
+ |
|
| 25 |
+extern int mapgsf(u8* a, int l, int &s); |
|
| 26 |
+ |
|
| 27 |
+#ifdef PROFILING |
|
| 28 |
+#include "prof/prof.h" |
|
| 29 |
+#endif |
|
| 30 |
+ |
|
| 31 |
+#ifdef __GNUC__ |
|
| 32 |
+#define _stricmp strcasecmp |
|
| 33 |
+#endif |
|
| 34 |
+ |
|
| 35 |
+extern int emulating; |
|
| 36 |
+ |
|
| 37 |
+int SWITicks = 0; |
|
| 38 |
+int IRQTicks = 0; |
|
| 39 |
+ |
|
| 40 |
+u32 mastercode = 0; |
|
| 41 |
+int layerEnableDelay = 0; |
|
| 42 |
+bool busPrefetch = false; |
|
| 43 |
+bool busPrefetchEnable = false; |
|
| 44 |
+u32 busPrefetchCount = 0; |
|
| 45 |
+int cpuDmaTicksToUpdate = 0; |
|
| 46 |
+int cpuDmaCount = 0; |
|
| 47 |
+bool cpuDmaHack = false; |
|
| 48 |
+u32 cpuDmaLast = 0; |
|
| 49 |
+int dummyAddress = 0; |
|
| 50 |
+ |
|
| 51 |
+bool cpuBreakLoop = false; |
|
| 52 |
+int cpuNextEvent = 0; |
|
| 53 |
+ |
|
| 54 |
+int gbaSaveType = 0; // used to remember the save type on reset |
|
| 55 |
+bool intState = false; |
|
| 56 |
+bool stopState = false; |
|
| 57 |
+bool holdState = false; |
|
| 58 |
+int holdType = 0; |
|
| 59 |
+bool cpuSramEnabled = true; |
|
| 60 |
+bool cpuFlashEnabled = true; |
|
| 61 |
+bool cpuEEPROMEnabled = true; |
|
| 62 |
+bool cpuEEPROMSensorEnabled = false; |
|
| 63 |
+ |
|
| 64 |
+u32 cpuPrefetch[2]; |
|
| 65 |
+ |
|
| 66 |
+int cpuTotalTicks = 0; |
|
| 67 |
+#ifdef PROFILING |
|
| 68 |
+int profilingTicks = 0; |
|
| 69 |
+int profilingTicksReload = 0; |
|
| 70 |
+static profile_segment *profilSegment = NULL; |
|
| 71 |
+#endif |
|
| 72 |
+ |
|
| 73 |
+#ifdef BKPT_SUPPORT |
|
| 74 |
+u8 freezeWorkRAM[0x40000]; |
|
| 75 |
+u8 freezeInternalRAM[0x8000]; |
|
| 76 |
+u8 freezeVRAM[0x18000]; |
|
| 77 |
+u8 freezePRAM[0x400]; |
|
| 78 |
+u8 freezeOAM[0x400]; |
|
| 79 |
+bool debugger_last; |
|
| 80 |
+#endif |
|
| 81 |
+ |
|
| 82 |
+int lcdTicks = (useBios && !skipBios) ? 1008 : 208; |
|
| 83 |
+u8 timerOnOffDelay = 0; |
|
| 84 |
+u16 timer0Value = 0; |
|
| 85 |
+bool timer0On = false; |
|
| 86 |
+int timer0Ticks = 0; |
|
| 87 |
+int timer0Reload = 0; |
|
| 88 |
+int timer0ClockReload = 0; |
|
| 89 |
+u16 timer1Value = 0; |
|
| 90 |
+bool timer1On = false; |
|
| 91 |
+int timer1Ticks = 0; |
|
| 92 |
+int timer1Reload = 0; |
|
| 93 |
+int timer1ClockReload = 0; |
|
| 94 |
+u16 timer2Value = 0; |
|
| 95 |
+bool timer2On = false; |
|
| 96 |
+int timer2Ticks = 0; |
|
| 97 |
+int timer2Reload = 0; |
|
| 98 |
+int timer2ClockReload = 0; |
|
| 99 |
+u16 timer3Value = 0; |
|
| 100 |
+bool timer3On = false; |
|
| 101 |
+int timer3Ticks = 0; |
|
| 102 |
+int timer3Reload = 0; |
|
| 103 |
+int timer3ClockReload = 0; |
|
| 104 |
+u32 dma0Source = 0; |
|
| 105 |
+u32 dma0Dest = 0; |
|
| 106 |
+u32 dma1Source = 0; |
|
| 107 |
+u32 dma1Dest = 0; |
|
| 108 |
+u32 dma2Source = 0; |
|
| 109 |
+u32 dma2Dest = 0; |
|
| 110 |
+u32 dma3Source = 0; |
|
| 111 |
+u32 dma3Dest = 0; |
|
| 112 |
+//void (*cpuSaveGameFunc)(u32,u8) = /*flashSaveDecide*/0; |
|
| 113 |
+//void (*renderLine)() = /*mode0RenderLine*/0; |
|
| 114 |
+bool fxOn = false; |
|
| 115 |
+bool windowOn = false; |
|
| 116 |
+int frameCount = 0; |
|
| 117 |
+char buffer[1024]; |
|
| 118 |
+u32 lastTime = 0; |
|
| 119 |
+int count = 0; |
|
| 120 |
+ |
|
| 121 |
+int capture = 0; |
|
| 122 |
+int capturePrevious = 0; |
|
| 123 |
+int captureNumber = 0; |
|
| 124 |
+ |
|
| 125 |
+const int TIMER_TICKS[4] = {
|
|
| 126 |
+ 0, |
|
| 127 |
+ 6, |
|
| 128 |
+ 8, |
|
| 129 |
+ 10 |
|
| 130 |
+}; |
|
| 131 |
+ |
|
| 132 |
+const u32 objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
|
|
| 133 |
+const u8 gamepakRamWaitState[4] = { 4, 3, 2, 8 };
|
|
| 134 |
+const u8 gamepakWaitState[4] = { 4, 3, 2, 8 };
|
|
| 135 |
+const u8 gamepakWaitState0[2] = { 2, 1 };
|
|
| 136 |
+const u8 gamepakWaitState1[2] = { 4, 1 };
|
|
| 137 |
+const u8 gamepakWaitState2[2] = { 8, 1 };
|
|
| 138 |
+const bool isInRom [16]= |
|
| 139 |
+ { false, false, false, false, false, false, false, false,
|
|
| 140 |
+ true, true, true, true, true, true, false, false }; |
|
| 141 |
+ |
|
| 142 |
+u8 memoryWait[16] = |
|
| 143 |
+ { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
|
|
| 144 |
+u8 memoryWait32[16] = |
|
| 145 |
+ { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
|
|
| 146 |
+u8 memoryWaitSeq[16] = |
|
| 147 |
+ { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
|
|
| 148 |
+u8 memoryWaitSeq32[16] = |
|
| 149 |
+ { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
|
|
| 150 |
+ |
|
| 151 |
+// The videoMemoryWait constants are used to add some waitstates |
|
| 152 |
+// if the opcode access video memory data outside of vblank/hblank |
|
| 153 |
+// It seems to happen on only one ticks for each pixel. |
|
| 154 |
+// Not used for now (too problematic with current code). |
|
| 155 |
+//const u8 videoMemoryWait[16] = |
|
| 156 |
+// {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
| 157 |
+ |
|
| 158 |
+ |
|
| 159 |
+u8 biosProtected[4]; |
|
| 160 |
+ |
|
| 161 |
+#ifdef WORDS_BIGENDIAN |
|
| 162 |
+bool cpuBiosSwapped = false; |
|
| 163 |
+#endif |
|
| 164 |
+ |
|
| 165 |
+u32 myROM[] = {
|
|
| 166 |
+0xEA000006, |
|
| 167 |
+0xEA000093, |
|
| 168 |
+0xEA000006, |
|
| 169 |
+0x00000000, |
|
| 170 |
+0x00000000, |
|
| 171 |
+0x00000000, |
|
| 172 |
+0xEA000088, |
|
| 173 |
+0x00000000, |
|
| 174 |
+0xE3A00302, |
|
| 175 |
+0xE1A0F000, |
|
| 176 |
+0xE92D5800, |
|
| 177 |
+0xE55EC002, |
|
| 178 |
+0xE28FB03C, |
|
| 179 |
+0xE79BC10C, |
|
| 180 |
+0xE14FB000, |
|
| 181 |
+0xE92D0800, |
|
| 182 |
+0xE20BB080, |
|
| 183 |
+0xE38BB01F, |
|
| 184 |
+0xE129F00B, |
|
| 185 |
+0xE92D4004, |
|
| 186 |
+0xE1A0E00F, |
|
| 187 |
+0xE12FFF1C, |
|
| 188 |
+0xE8BD4004, |
|
| 189 |
+0xE3A0C0D3, |
|
| 190 |
+0xE129F00C, |
|
| 191 |
+0xE8BD0800, |
|
| 192 |
+0xE169F00B, |
|
| 193 |
+0xE8BD5800, |
|
| 194 |
+0xE1B0F00E, |
|
| 195 |
+0x0000009C, |
|
| 196 |
+0x0000009C, |
|
| 197 |
+0x0000009C, |
|
| 198 |
+0x0000009C, |
|
| 199 |
+0x000001F8, |
|
| 200 |
+0x000001F0, |
|
| 201 |
+0x000000AC, |
|
| 202 |
+0x000000A0, |
|
| 203 |
+0x000000FC, |
|
| 204 |
+0x00000168, |
|
| 205 |
+0xE12FFF1E, |
|
| 206 |
+0xE1A03000, |
|
| 207 |
+0xE1A00001, |
|
| 208 |
+0xE1A01003, |
|
| 209 |
+0xE2113102, |
|
| 210 |
+0x42611000, |
|
| 211 |
+0xE033C040, |
|
| 212 |
+0x22600000, |
|
| 213 |
+0xE1B02001, |
|
| 214 |
+0xE15200A0, |
|
| 215 |
+0x91A02082, |
|
| 216 |
+0x3AFFFFFC, |
|
| 217 |
+0xE1500002, |
|
| 218 |
+0xE0A33003, |
|
| 219 |
+0x20400002, |
|
| 220 |
+0xE1320001, |
|
| 221 |
+0x11A020A2, |
|
| 222 |
+0x1AFFFFF9, |
|
| 223 |
+0xE1A01000, |
|
| 224 |
+0xE1A00003, |
|
| 225 |
+0xE1B0C08C, |
|
| 226 |
+0x22600000, |
|
| 227 |
+0x42611000, |
|
| 228 |
+0xE12FFF1E, |
|
| 229 |
+0xE92D0010, |
|
| 230 |
+0xE1A0C000, |
|
| 231 |
+0xE3A01001, |
|
| 232 |
+0xE1500001, |
|
| 233 |
+0x81A000A0, |
|
| 234 |
+0x81A01081, |
|
| 235 |
+0x8AFFFFFB, |
|
| 236 |
+0xE1A0000C, |
|
| 237 |
+0xE1A04001, |
|
| 238 |
+0xE3A03000, |
|
| 239 |
+0xE1A02001, |
|
| 240 |
+0xE15200A0, |
|
| 241 |
+0x91A02082, |
|
| 242 |
+0x3AFFFFFC, |
|
| 243 |
+0xE1500002, |
|
| 244 |
+0xE0A33003, |
|
| 245 |
+0x20400002, |
|
| 246 |
+0xE1320001, |
|
| 247 |
+0x11A020A2, |
|
| 248 |
+0x1AFFFFF9, |
|
| 249 |
+0xE0811003, |
|
| 250 |
+0xE1B010A1, |
|
| 251 |
+0xE1510004, |
|
| 252 |
+0x3AFFFFEE, |
|
| 253 |
+0xE1A00004, |
|
| 254 |
+0xE8BD0010, |
|
| 255 |
+0xE12FFF1E, |
|
| 256 |
+0xE0010090, |
|
| 257 |
+0xE1A01741, |
|
| 258 |
+0xE2611000, |
|
| 259 |
+0xE3A030A9, |
|
| 260 |
+0xE0030391, |
|
| 261 |
+0xE1A03743, |
|
| 262 |
+0xE2833E39, |
|
| 263 |
+0xE0030391, |
|
| 264 |
+0xE1A03743, |
|
| 265 |
+0xE2833C09, |
|
| 266 |
+0xE283301C, |
|
| 267 |
+0xE0030391, |
|
| 268 |
+0xE1A03743, |
|
| 269 |
+0xE2833C0F, |
|
| 270 |
+0xE28330B6, |
|
| 271 |
+0xE0030391, |
|
| 272 |
+0xE1A03743, |
|
| 273 |
+0xE2833C16, |
|
| 274 |
+0xE28330AA, |
|
| 275 |
+0xE0030391, |
|
| 276 |
+0xE1A03743, |
|
| 277 |
+0xE2833A02, |
|
| 278 |
+0xE2833081, |
|
| 279 |
+0xE0030391, |
|
| 280 |
+0xE1A03743, |
|
| 281 |
+0xE2833C36, |
|
| 282 |
+0xE2833051, |
|
| 283 |
+0xE0030391, |
|
| 284 |
+0xE1A03743, |
|
| 285 |
+0xE2833CA2, |
|
| 286 |
+0xE28330F9, |
|
| 287 |
+0xE0000093, |
|
| 288 |
+0xE1A00840, |
|
| 289 |
+0xE12FFF1E, |
|
| 290 |
+0xE3A00001, |
|
| 291 |
+0xE3A01001, |
|
| 292 |
+0xE92D4010, |
|
| 293 |
+0xE3A03000, |
|
| 294 |
+0xE3A04001, |
|
| 295 |
+0xE3500000, |
|
| 296 |
+0x1B000004, |
|
| 297 |
+0xE5CC3301, |
|
| 298 |
+0xEB000002, |
|
| 299 |
+0x0AFFFFFC, |
|
| 300 |
+0xE8BD4010, |
|
| 301 |
+0xE12FFF1E, |
|
| 302 |
+0xE3A0C301, |
|
| 303 |
+0xE5CC3208, |
|
| 304 |
+0xE15C20B8, |
|
| 305 |
+0xE0110002, |
|
| 306 |
+0x10222000, |
|
| 307 |
+0x114C20B8, |
|
| 308 |
+0xE5CC4208, |
|
| 309 |
+0xE12FFF1E, |
|
| 310 |
+0xE92D500F, |
|
| 311 |
+0xE3A00301, |
|
| 312 |
+0xE1A0E00F, |
|
| 313 |
+0xE510F004, |
|
| 314 |
+0xE8BD500F, |
|
| 315 |
+0xE25EF004, |
|
| 316 |
+0xE59FD044, |
|
| 317 |
+0xE92D5000, |
|
| 318 |
+0xE14FC000, |
|
| 319 |
+0xE10FE000, |
|
| 320 |
+0xE92D5000, |
|
| 321 |
+0xE3A0C302, |
|
| 322 |
+0xE5DCE09C, |
|
| 323 |
+0xE35E00A5, |
|
| 324 |
+0x1A000004, |
|
| 325 |
+0x05DCE0B4, |
|
| 326 |
+0x021EE080, |
|
| 327 |
+0xE28FE004, |
|
| 328 |
+0x159FF018, |
|
| 329 |
+0x059FF018, |
|
| 330 |
+0xE59FD018, |
|
| 331 |
+0xE8BD5000, |
|
| 332 |
+0xE169F00C, |
|
| 333 |
+0xE8BD5000, |
|
| 334 |
+0xE25EF004, |
|
| 335 |
+0x03007FF0, |
|
| 336 |
+0x09FE2000, |
|
| 337 |
+0x09FFC000, |
|
| 338 |
+0x03007FE0 |
|
| 339 |
+}; |
|
| 340 |
+ |
|
| 341 |
+/*variable_desc saveGameStruct[] = {
|
|
| 342 |
+ { &DISPCNT , sizeof(u16) },
|
|
| 343 |
+ { &DISPSTAT , sizeof(u16) },
|
|
| 344 |
+ { &VCOUNT , sizeof(u16) },
|
|
| 345 |
+ { &BG0CNT , sizeof(u16) },
|
|
| 346 |
+ { &BG1CNT , sizeof(u16) },
|
|
| 347 |
+ { &BG2CNT , sizeof(u16) },
|
|
| 348 |
+ { &BG3CNT , sizeof(u16) },
|
|
| 349 |
+ { &BG0HOFS , sizeof(u16) },
|
|
| 350 |
+ { &BG0VOFS , sizeof(u16) },
|
|
| 351 |
+ { &BG1HOFS , sizeof(u16) },
|
|
| 352 |
+ { &BG1VOFS , sizeof(u16) },
|
|
| 353 |
+ { &BG2HOFS , sizeof(u16) },
|
|
| 354 |
+ { &BG2VOFS , sizeof(u16) },
|
|
| 355 |
+ { &BG3HOFS , sizeof(u16) },
|
|
| 356 |
+ { &BG3VOFS , sizeof(u16) },
|
|
| 357 |
+ { &BG2PA , sizeof(u16) },
|
|
| 358 |
+ { &BG2PB , sizeof(u16) },
|
|
| 359 |
+ { &BG2PC , sizeof(u16) },
|
|
| 360 |
+ { &BG2PD , sizeof(u16) },
|
|
| 361 |
+ { &BG2X_L , sizeof(u16) },
|
|
| 362 |
+ { &BG2X_H , sizeof(u16) },
|
|
| 363 |
+ { &BG2Y_L , sizeof(u16) },
|
|
| 364 |
+ { &BG2Y_H , sizeof(u16) },
|
|
| 365 |
+ { &BG3PA , sizeof(u16) },
|
|
| 366 |
+ { &BG3PB , sizeof(u16) },
|
|
| 367 |
+ { &BG3PC , sizeof(u16) },
|
|
| 368 |
+ { &BG3PD , sizeof(u16) },
|
|
| 369 |
+ { &BG3X_L , sizeof(u16) },
|
|
| 370 |
+ { &BG3X_H , sizeof(u16) },
|
|
| 371 |
+ { &BG3Y_L , sizeof(u16) },
|
|
| 372 |
+ { &BG3Y_H , sizeof(u16) },
|
|
| 373 |
+ { &WIN0H , sizeof(u16) },
|
|
| 374 |
+ { &WIN1H , sizeof(u16) },
|
|
| 375 |
+ { &WIN0V , sizeof(u16) },
|
|
| 376 |
+ { &WIN1V , sizeof(u16) },
|
|
| 377 |
+ { &WININ , sizeof(u16) },
|
|
| 378 |
+ { &WINOUT , sizeof(u16) },
|
|
| 379 |
+ { &MOSAIC , sizeof(u16) },
|
|
| 380 |
+ { &BLDMOD , sizeof(u16) },
|
|
| 381 |
+ { &COLEV , sizeof(u16) },
|
|
| 382 |
+ { &COLY , sizeof(u16) },
|
|
| 383 |
+ { &DM0SAD_L , sizeof(u16) },
|
|
| 384 |
+ { &DM0SAD_H , sizeof(u16) },
|
|
| 385 |
+ { &DM0DAD_L , sizeof(u16) },
|
|
| 386 |
+ { &DM0DAD_H , sizeof(u16) },
|
|
| 387 |
+ { &DM0CNT_L , sizeof(u16) },
|
|
| 388 |
+ { &DM0CNT_H , sizeof(u16) },
|
|
| 389 |
+ { &DM1SAD_L , sizeof(u16) },
|
|
| 390 |
+ { &DM1SAD_H , sizeof(u16) },
|
|
| 391 |
+ { &DM1DAD_L , sizeof(u16) },
|
|
| 392 |
+ { &DM1DAD_H , sizeof(u16) },
|
|
| 393 |
+ { &DM1CNT_L , sizeof(u16) },
|
|
| 394 |
+ { &DM1CNT_H , sizeof(u16) },
|
|
| 395 |
+ { &DM2SAD_L , sizeof(u16) },
|
|
| 396 |
+ { &DM2SAD_H , sizeof(u16) },
|
|
| 397 |
+ { &DM2DAD_L , sizeof(u16) },
|
|
| 398 |
+ { &DM2DAD_H , sizeof(u16) },
|
|
| 399 |
+ { &DM2CNT_L , sizeof(u16) },
|
|
| 400 |
+ { &DM2CNT_H , sizeof(u16) },
|
|
| 401 |
+ { &DM3SAD_L , sizeof(u16) },
|
|
| 402 |
+ { &DM3SAD_H , sizeof(u16) },
|
|
| 403 |
+ { &DM3DAD_L , sizeof(u16) },
|
|
| 404 |
+ { &DM3DAD_H , sizeof(u16) },
|
|
| 405 |
+ { &DM3CNT_L , sizeof(u16) },
|
|
| 406 |
+ { &DM3CNT_H , sizeof(u16) },
|
|
| 407 |
+ { &TM0D , sizeof(u16) },
|
|
| 408 |
+ { &TM0CNT , sizeof(u16) },
|
|
| 409 |
+ { &TM1D , sizeof(u16) },
|
|
| 410 |
+ { &TM1CNT , sizeof(u16) },
|
|
| 411 |
+ { &TM2D , sizeof(u16) },
|
|
| 412 |
+ { &TM2CNT , sizeof(u16) },
|
|
| 413 |
+ { &TM3D , sizeof(u16) },
|
|
| 414 |
+ { &TM3CNT , sizeof(u16) },
|
|
| 415 |
+ { &P1 , sizeof(u16) },
|
|
| 416 |
+ { &IE , sizeof(u16) },
|
|
| 417 |
+ { &IF , sizeof(u16) },
|
|
| 418 |
+ { &IME , sizeof(u16) },
|
|
| 419 |
+ { &holdState, sizeof(bool) },
|
|
| 420 |
+ { &holdType, sizeof(int) },
|
|
| 421 |
+ { &lcdTicks, sizeof(int) },
|
|
| 422 |
+ { &timer0On , sizeof(bool) },
|
|
| 423 |
+ { &timer0Ticks , sizeof(int) },
|
|
| 424 |
+ { &timer0Reload , sizeof(int) },
|
|
| 425 |
+ { &timer0ClockReload , sizeof(int) },
|
|
| 426 |
+ { &timer1On , sizeof(bool) },
|
|
| 427 |
+ { &timer1Ticks , sizeof(int) },
|
|
| 428 |
+ { &timer1Reload , sizeof(int) },
|
|
| 429 |
+ { &timer1ClockReload , sizeof(int) },
|
|
| 430 |
+ { &timer2On , sizeof(bool) },
|
|
| 431 |
+ { &timer2Ticks , sizeof(int) },
|
|
| 432 |
+ { &timer2Reload , sizeof(int) },
|
|
| 433 |
+ { &timer2ClockReload , sizeof(int) },
|
|
| 434 |
+ { &timer3On , sizeof(bool) },
|
|
| 435 |
+ { &timer3Ticks , sizeof(int) },
|
|
| 436 |
+ { &timer3Reload , sizeof(int) },
|
|
| 437 |
+ { &timer3ClockReload , sizeof(int) },
|
|
| 438 |
+ { &dma0Source , sizeof(u32) },
|
|
| 439 |
+ { &dma0Dest , sizeof(u32) },
|
|
| 440 |
+ { &dma1Source , sizeof(u32) },
|
|
| 441 |
+ { &dma1Dest , sizeof(u32) },
|
|
| 442 |
+ { &dma2Source , sizeof(u32) },
|
|
| 443 |
+ { &dma2Dest , sizeof(u32) },
|
|
| 444 |
+ { &dma3Source , sizeof(u32) },
|
|
| 445 |
+ { &dma3Dest , sizeof(u32) },
|
|
| 446 |
+ { &fxOn, sizeof(bool) },
|
|
| 447 |
+ { &windowOn, sizeof(bool) },
|
|
| 448 |
+ { &N_FLAG , sizeof(bool) },
|
|
| 449 |
+ { &C_FLAG , sizeof(bool) },
|
|
| 450 |
+ { &Z_FLAG , sizeof(bool) },
|
|
| 451 |
+ { &V_FLAG , sizeof(bool) },
|
|
| 452 |
+ { &armState , sizeof(bool) },
|
|
| 453 |
+ { &armIrqEnable , sizeof(bool) },
|
|
| 454 |
+ { &armNextPC , sizeof(u32) },
|
|
| 455 |
+ { &armMode , sizeof(int) },
|
|
| 456 |
+ { &saveType , sizeof(int) },
|
|
| 457 |
+ { NULL, 0 }
|
|
| 458 |
+};*/ |
|
| 459 |
+ |
|
| 460 |
+static int romSize = 0x2000000; |
|
| 461 |
+ |
|
| 462 |
+#ifdef PROFILING |
|
| 463 |
+void cpuProfil(profile_segment *seg) |
|
| 464 |
+{
|
|
| 465 |
+ profilSegment = seg; |
|
| 466 |
+} |
|
| 467 |
+ |
|
| 468 |
+void cpuEnableProfiling(int hz) |
|
| 469 |
+{
|
|
| 470 |
+ if(hz == 0) |
|
| 471 |
+ hz = 100; |
|
| 472 |
+ profilingTicks = profilingTicksReload = 16777216 / hz; |
|
| 473 |
+ profSetHertz(hz); |
|
| 474 |
+} |
|
| 475 |
+#endif |
|
| 476 |
+ |
|
| 477 |
+ |
|
| 478 |
+inline int CPUUpdateTicks() |
|
| 479 |
+{
|
|
| 480 |
+ int cpuLoopTicks = lcdTicks; |
|
| 481 |
+ |
|
| 482 |
+ if(soundTicks < cpuLoopTicks) |
|
| 483 |
+ cpuLoopTicks = soundTicks; |
|
| 484 |
+ |
|
| 485 |
+ if(timer0On && (timer0Ticks < cpuLoopTicks)) {
|
|
| 486 |
+ cpuLoopTicks = timer0Ticks; |
|
| 487 |
+ } |
|
| 488 |
+ if(timer1On && !(TM1CNT & 4) && (timer1Ticks < cpuLoopTicks)) {
|
|
| 489 |
+ cpuLoopTicks = timer1Ticks; |
|
| 490 |
+ } |
|
| 491 |
+ if(timer2On && !(TM2CNT & 4) && (timer2Ticks < cpuLoopTicks)) {
|
|
| 492 |
+ cpuLoopTicks = timer2Ticks; |
|
| 493 |
+ } |
|
| 494 |
+ if(timer3On && !(TM3CNT & 4) && (timer3Ticks < cpuLoopTicks)) {
|
|
| 495 |
+ cpuLoopTicks = timer3Ticks; |
|
| 496 |
+ } |
|
| 497 |
+#ifdef PROFILING |
|
| 498 |
+ if(profilingTicksReload != 0) {
|
|
| 499 |
+ if(profilingTicks < cpuLoopTicks) {
|
|
| 500 |
+ cpuLoopTicks = profilingTicks; |
|
| 501 |
+ } |
|
| 502 |
+ } |
|
| 503 |
+#endif |
|
| 504 |
+ |
|
| 505 |
+ if (SWITicks) {
|
|
| 506 |
+ if (SWITicks < cpuLoopTicks) |
|
| 507 |
+ cpuLoopTicks = SWITicks; |
|
| 508 |
+ } |
|
| 509 |
+ |
|
| 510 |
+ if (IRQTicks) {
|
|
| 511 |
+ if (IRQTicks < cpuLoopTicks) |
|
| 512 |
+ cpuLoopTicks = IRQTicks; |
|
| 513 |
+ } |
|
| 514 |
+ |
|
| 515 |
+ return cpuLoopTicks; |
|
| 516 |
+} |
|
| 517 |
+ |
|
| 518 |
+/*void CPUUpdateWindow0() |
|
| 519 |
+{
|
|
| 520 |
+ int x00 = WIN0H>>8; |
|
| 521 |
+ int x01 = WIN0H & 255; |
|
| 522 |
+ |
|
| 523 |
+ if(x00 <= x01) {
|
|
| 524 |
+ for(int i = 0; i < 240; i++) {
|
|
| 525 |
+ gfxInWin0[i] = (i >= x00 && i < x01); |
|
| 526 |
+ } |
|
| 527 |
+ } else {
|
|
| 528 |
+ for(int i = 0; i < 240; i++) {
|
|
| 529 |
+ gfxInWin0[i] = (i >= x00 || i < x01); |
|
| 530 |
+ } |
|
| 531 |
+ } |
|
| 532 |
+}*/ |
|
| 533 |
+ |
|
| 534 |
+/*void CPUUpdateWindow1() |
|
| 535 |
+{
|
|
| 536 |
+ int x00 = WIN1H>>8; |
|
| 537 |
+ int x01 = WIN1H & 255; |
|
| 538 |
+ |
|
| 539 |
+ if(x00 <= x01) {
|
|
| 540 |
+ for(int i = 0; i < 240; i++) {
|
|
| 541 |
+ gfxInWin1[i] = (i >= x00 && i < x01); |
|
| 542 |
+ } |
|
| 543 |
+ } else {
|
|
| 544 |
+ for(int i = 0; i < 240; i++) {
|
|
| 545 |
+ gfxInWin1[i] = (i >= x00 || i < x01); |
|
| 546 |
+ } |
|
| 547 |
+ } |
|
| 548 |
+}*/ |
|
| 549 |
+ |
|
| 550 |
+extern u32 line0[240]; |
|
| 551 |
+extern u32 line1[240]; |
|
| 552 |
+extern u32 line2[240]; |
|
| 553 |
+extern u32 line3[240]; |
|
| 554 |
+ |
|
| 555 |
+#define CLEAR_ARRAY(a) \ |
|
| 556 |
+ {\
|
|
| 557 |
+ u32 *array = (a);\ |
|
| 558 |
+ for(int i = 0; i < 240; i++) {\
|
|
| 559 |
+ *array++ = 0x80000000;\ |
|
| 560 |
+ }\ |
|
| 561 |
+ }\ |
|
| 562 |
+ |
|
| 563 |
+/*void CPUUpdateRenderBuffers(bool force) |
|
| 564 |
+{
|
|
| 565 |
+ if(!(layerEnable & 0x0100) || force) {
|
|
| 566 |
+ CLEAR_ARRAY(line0); |
|
| 567 |
+ } |
|
| 568 |
+ if(!(layerEnable & 0x0200) || force) {
|
|
| 569 |
+ CLEAR_ARRAY(line1); |
|
| 570 |
+ } |
|
| 571 |
+ if(!(layerEnable & 0x0400) || force) {
|
|
| 572 |
+ CLEAR_ARRAY(line2); |
|
| 573 |
+ } |
|
| 574 |
+ if(!(layerEnable & 0x0800) || force) {
|
|
| 575 |
+ CLEAR_ARRAY(line3); |
|
| 576 |
+ } |
|
| 577 |
+}*/ |
|
| 578 |
+ |
|
| 579 |
+/*static bool CPUWriteState(gzFile gzFile) |
|
| 580 |
+{
|
|
| 581 |
+ utilWriteInt(gzFile, SAVE_GAME_VERSION); |
|
| 582 |
+ |
|
| 583 |
+ utilGzWrite(gzFile, &rom[0xa0], 16); |
|
| 584 |
+ |
|
| 585 |
+ utilWriteInt(gzFile, useBios); |
|
| 586 |
+ |
|
| 587 |
+ utilGzWrite(gzFile, ®[0], sizeof(reg)); |
|
| 588 |
+ |
|
| 589 |
+ utilWriteData(gzFile, saveGameStruct); |
|
| 590 |
+ |
|
| 591 |
+ // new to version 0.7.1 |
|
| 592 |
+ utilWriteInt(gzFile, stopState); |
|
| 593 |
+ // new to version 0.8 |
|
| 594 |
+ utilWriteInt(gzFile, IRQTicks); |
|
| 595 |
+ |
|
| 596 |
+ utilGzWrite(gzFile, internalRAM, 0x8000); |
|
| 597 |
+ utilGzWrite(gzFile, paletteRAM, 0x400); |
|
| 598 |
+ utilGzWrite(gzFile, workRAM, 0x40000); |
|
| 599 |
+ utilGzWrite(gzFile, vram, 0x20000); |
|
| 600 |
+ utilGzWrite(gzFile, oam, 0x400); |
|
| 601 |
+ utilGzWrite(gzFile, pix, 4*241*162); |
|
| 602 |
+ utilGzWrite(gzFile, ioMem, 0x400); |
|
| 603 |
+ |
|
| 604 |
+ eepromSaveGame(gzFile); |
|
| 605 |
+ flashSaveGame(gzFile); |
|
| 606 |
+ soundSaveGame(gzFile); |
|
| 607 |
+ |
|
| 608 |
+ cheatsSaveGame(gzFile); |
|
| 609 |
+ |
|
| 610 |
+ // version 1.5 |
|
| 611 |
+ rtcSaveGame(gzFile); |
|
| 612 |
+ |
|
| 613 |
+ return true; |
|
| 614 |
+} |
|
| 615 |
+ |
|
| 616 |
+bool CPUWriteState(const char *file) |
|
| 617 |
+{
|
|
| 618 |
+ gzFile gzFile = utilGzOpen(file, "wb"); |
|
| 619 |
+ |
|
| 620 |
+ if(gzFile == NULL) {
|
|
| 621 |
+ systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), file);
|
|
| 622 |
+ return false; |
|
| 623 |
+ } |
|
| 624 |
+ |
|
| 625 |
+ bool res = CPUWriteState(gzFile); |
|
| 626 |
+ |
|
| 627 |
+ utilGzClose(gzFile); |
|
| 628 |
+ |
|
| 629 |
+ return res; |
|
| 630 |
+} |
|
| 631 |
+ |
|
| 632 |
+bool CPUWriteMemState(char *memory, int available) |
|
| 633 |
+{
|
|
| 634 |
+ gzFile gzFile = utilMemGzOpen(memory, available, "w"); |
|
| 635 |
+ |
|
| 636 |
+ if(gzFile == NULL) {
|
|
| 637 |
+ return false; |
|
| 638 |
+ } |
|
| 639 |
+ |
|
| 640 |
+ bool res = CPUWriteState(gzFile); |
|
| 641 |
+ |
|
| 642 |
+ long pos = utilGzMemTell(gzFile)+8; |
|
| 643 |
+ |
|
| 644 |
+ if(pos >= (available)) |
|
| 645 |
+ res = false; |
|
| 646 |
+ |
|
| 647 |
+ utilGzClose(gzFile); |
|
| 648 |
+ |
|
| 649 |
+ return res; |
|
| 650 |
+} |
|
| 651 |
+ |
|
| 652 |
+static bool CPUReadState(gzFile gzFile) |
|
| 653 |
+{
|
|
| 654 |
+ int version = utilReadInt(gzFile); |
|
| 655 |
+ |
|
| 656 |
+ if(version > SAVE_GAME_VERSION || version < SAVE_GAME_VERSION_1) {
|
|
| 657 |
+ systemMessage(MSG_UNSUPPORTED_VBA_SGM, |
|
| 658 |
+ N_("Unsupported VisualBoyAdvance save game version %d"),
|
|
| 659 |
+ version); |
|
| 660 |
+ return false; |
|
| 661 |
+ } |
|
| 662 |
+ |
|
| 663 |
+ u8 romname[17]; |
|
| 664 |
+ |
|
| 665 |
+ utilGzRead(gzFile, romname, 16); |
|
| 666 |
+ |
|
| 667 |
+ if(memcmp(&rom[0xa0], romname, 16) != 0) {
|
|
| 668 |
+ romname[16]=0; |
|
| 669 |
+ for(int i = 0; i < 16; i++) |
|
| 670 |
+ if(romname[i] < 32) |
|
| 671 |
+ romname[i] = 32; |
|
| 672 |
+ systemMessage(MSG_CANNOT_LOAD_SGM, N_("Cannot load save game for %s"), romname);
|
|
| 673 |
+ return false; |
|
| 674 |
+ } |
|
| 675 |
+ |
|
| 676 |
+ bool ub = utilReadInt(gzFile) ? true : false; |
|
| 677 |
+ |
|
| 678 |
+ if(ub != useBios) {
|
|
| 679 |
+ if(useBios) |
|
| 680 |
+ systemMessage(MSG_SAVE_GAME_NOT_USING_BIOS, |
|
| 681 |
+ N_("Save game is not using the BIOS files"));
|
|
| 682 |
+ else |
|
| 683 |
+ systemMessage(MSG_SAVE_GAME_USING_BIOS, |
|
| 684 |
+ N_("Save game is using the BIOS file"));
|
|
| 685 |
+ return false; |
|
| 686 |
+ } |
|
| 687 |
+ |
|
| 688 |
+ utilGzRead(gzFile, ®[0], sizeof(reg)); |
|
| 689 |
+ |
|
| 690 |
+ utilReadData(gzFile, saveGameStruct); |
|
| 691 |
+ |
|
| 692 |
+ if(version < SAVE_GAME_VERSION_3) |
|
| 693 |
+ stopState = false; |
|
| 694 |
+ else |
|
| 695 |
+ stopState = utilReadInt(gzFile) ? true : false; |
|
| 696 |
+ |
|
| 697 |
+ if(version < SAVE_GAME_VERSION_4) |
|
| 698 |
+ {
|
|
| 699 |
+ IRQTicks = 0; |
|
| 700 |
+ intState = false; |
|
| 701 |
+ } |
|
| 702 |
+ else |
|
| 703 |
+ {
|
|
| 704 |
+ IRQTicks = utilReadInt(gzFile); |
|
| 705 |
+ if (IRQTicks>0) |
|
| 706 |
+ intState = true; |
|
| 707 |
+ else |
|
| 708 |
+ {
|
|
| 709 |
+ intState = false; |
|
| 710 |
+ IRQTicks = 0; |
|
| 711 |
+ } |
|
| 712 |
+ } |
|
| 713 |
+ |
|
| 714 |
+ utilGzRead(gzFile, internalRAM, 0x8000); |
|
| 715 |
+ utilGzRead(gzFile, paletteRAM, 0x400); |
|
| 716 |
+ utilGzRead(gzFile, workRAM, 0x40000); |
|
| 717 |
+ utilGzRead(gzFile, vram, 0x20000); |
|
| 718 |
+ utilGzRead(gzFile, oam, 0x400); |
|
| 719 |
+ if(version < SAVE_GAME_VERSION_6) |
|
| 720 |
+ utilGzRead(gzFile, pix, 4*240*160); |
|
| 721 |
+ else |
|
| 722 |
+ utilGzRead(gzFile, pix, 4*241*162); |
|
| 723 |
+ utilGzRead(gzFile, ioMem, 0x400); |
|
| 724 |
+ |
|
| 725 |
+ if(skipSaveGameBattery) {
|
|
| 726 |
+ // skip eeprom data |
|
| 727 |
+ eepromReadGameSkip(gzFile, version); |
|
| 728 |
+ // skip flash data |
|
| 729 |
+ flashReadGameSkip(gzFile, version); |
|
| 730 |
+ } else {
|
|
| 731 |
+ eepromReadGame(gzFile, version); |
|
| 732 |
+ flashReadGame(gzFile, version); |
|
| 733 |
+ } |
|
| 734 |
+ soundReadGame(gzFile, version); |
|
| 735 |
+ |
|
| 736 |
+ if(version > SAVE_GAME_VERSION_1) {
|
|
| 737 |
+ if(skipSaveGameCheats) {
|
|
| 738 |
+ // skip cheats list data |
|
| 739 |
+ cheatsReadGameSkip(gzFile, version); |
|
| 740 |
+ } else {
|
|
| 741 |
+ cheatsReadGame(gzFile, version); |
|
| 742 |
+ } |
|
| 743 |
+ } |
|
| 744 |
+ if(version > SAVE_GAME_VERSION_6) {
|
|
| 745 |
+ rtcReadGame(gzFile); |
|
| 746 |
+ } |
|
| 747 |
+ |
|
| 748 |
+ if(version <= SAVE_GAME_VERSION_7) {
|
|
| 749 |
+ u32 temp; |
|
| 750 |
+#define SWAP(a,b,c) \ |
|
| 751 |
+ temp = (a);\ |
|
| 752 |
+ (a) = (b)<<16|(c);\ |
|
| 753 |
+ (b) = (temp) >> 16;\ |
|
| 754 |
+ (c) = (temp) & 0xFFFF; |
|
| 755 |
+ |
|
| 756 |
+ SWAP(dma0Source, DM0SAD_H, DM0SAD_L); |
|
| 757 |
+ SWAP(dma0Dest, DM0DAD_H, DM0DAD_L); |
|
| 758 |
+ SWAP(dma1Source, DM1SAD_H, DM1SAD_L); |
|
| 759 |
+ SWAP(dma1Dest, DM1DAD_H, DM1DAD_L); |
|
| 760 |
+ SWAP(dma2Source, DM2SAD_H, DM2SAD_L); |
|
| 761 |
+ SWAP(dma2Dest, DM2DAD_H, DM2DAD_L); |
|
| 762 |
+ SWAP(dma3Source, DM3SAD_H, DM3SAD_L); |
|
| 763 |
+ SWAP(dma3Dest, DM3DAD_H, DM3DAD_L); |
|
| 764 |
+ } |
|
| 765 |
+ |
|
| 766 |
+ if(version <= SAVE_GAME_VERSION_8) {
|
|
| 767 |
+ timer0ClockReload = TIMER_TICKS[TM0CNT & 3]; |
|
| 768 |
+ timer1ClockReload = TIMER_TICKS[TM1CNT & 3]; |
|
| 769 |
+ timer2ClockReload = TIMER_TICKS[TM2CNT & 3]; |
|
| 770 |
+ timer3ClockReload = TIMER_TICKS[TM3CNT & 3]; |
|
| 771 |
+ |
|
| 772 |
+ timer0Ticks = ((0x10000 - TM0D) << timer0ClockReload) - timer0Ticks; |
|
| 773 |
+ timer1Ticks = ((0x10000 - TM1D) << timer1ClockReload) - timer1Ticks; |
|
| 774 |
+ timer2Ticks = ((0x10000 - TM2D) << timer2ClockReload) - timer2Ticks; |
|
| 775 |
+ timer3Ticks = ((0x10000 - TM3D) << timer3ClockReload) - timer3Ticks; |
|
| 776 |
+ interp_rate(); |
|
| 777 |
+ } |
|
| 778 |
+ |
|
| 779 |
+ // set pointers! |
|
| 780 |
+ layerEnable = layerSettings & DISPCNT; |
|
| 781 |
+ |
|
| 782 |
+ CPUUpdateRender(); |
|
| 783 |
+ //CPUUpdateRenderBuffers(true); |
|
| 784 |
+ //CPUUpdateWindow0(); |
|
| 785 |
+ //CPUUpdateWindow1(); |
|
| 786 |
+ gbaSaveType = 0; |
|
| 787 |
+ switch(saveType) {
|
|
| 788 |
+ case 0: |
|
| 789 |
+ cpuSaveGameFunc = flashSaveDecide; |
|
| 790 |
+ break; |
|
| 791 |
+ case 1: |
|
| 792 |
+ cpuSaveGameFunc = sramWrite; |
|
| 793 |
+ gbaSaveType = 1; |
|
| 794 |
+ break; |
|
| 795 |
+ case 2: |
|
| 796 |
+ cpuSaveGameFunc = flashWrite; |
|
| 797 |
+ gbaSaveType = 2; |
|
| 798 |
+ break; |
|
| 799 |
+ case 3: |
|
| 800 |
+ break; |
|
| 801 |
+ case 5: |
|
| 802 |
+ gbaSaveType = 5; |
|
| 803 |
+ break; |
|
| 804 |
+ default: |
|
| 805 |
+ systemMessage(MSG_UNSUPPORTED_SAVE_TYPE, |
|
| 806 |
+ N_("Unsupported save type %d"), saveType);
|
|
| 807 |
+ break; |
|
| 808 |
+ } |
|
| 809 |
+ if(eepromInUse) |
|
| 810 |
+ gbaSaveType = 3; |
|
| 811 |
+ |
|
| 812 |
+ systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 813 |
+ if(armState) {
|
|
| 814 |
+ ARM_PREFETCH; |
|
| 815 |
+ } else {
|
|
| 816 |
+ THUMB_PREFETCH; |
|
| 817 |
+ } |
|
| 818 |
+ |
|
| 819 |
+ CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204)); |
|
| 820 |
+ |
|
| 821 |
+ return true; |
|
| 822 |
+} |
|
| 823 |
+ |
|
| 824 |
+bool CPUReadMemState(char *memory, int available) |
|
| 825 |
+{
|
|
| 826 |
+ gzFile gzFile = utilMemGzOpen(memory, available, "r"); |
|
| 827 |
+ |
|
| 828 |
+ bool res = CPUReadState(gzFile); |
|
| 829 |
+ |
|
| 830 |
+ utilGzClose(gzFile); |
|
| 831 |
+ |
|
| 832 |
+ return res; |
|
| 833 |
+} |
|
| 834 |
+ |
|
| 835 |
+bool CPUReadState(const char * file) |
|
| 836 |
+{
|
|
| 837 |
+ gzFile gzFile = utilGzOpen(file, "rb"); |
|
| 838 |
+ |
|
| 839 |
+ if(gzFile == NULL) |
|
| 840 |
+ return false; |
|
| 841 |
+ |
|
| 842 |
+ bool res = CPUReadState(gzFile); |
|
| 843 |
+ |
|
| 844 |
+ utilGzClose(gzFile); |
|
| 845 |
+ |
|
| 846 |
+ return res; |
|
| 847 |
+} |
|
| 848 |
+ |
|
| 849 |
+bool CPUExportEepromFile(const char *fileName) |
|
| 850 |
+{
|
|
| 851 |
+ if(eepromInUse) {
|
|
| 852 |
+ FILE *file = fopen(fileName, "wb"); |
|
| 853 |
+ |
|
| 854 |
+ if(!file) {
|
|
| 855 |
+ systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
|
|
| 856 |
+ fileName); |
|
| 857 |
+ return false; |
|
| 858 |
+ } |
|
| 859 |
+ |
|
| 860 |
+ for(int i = 0; i < eepromSize;) {
|
|
| 861 |
+ for(int j = 0; j < 8; j++) {
|
|
| 862 |
+ if(fwrite(&eepromData[i+7-j], 1, 1, file) != 1) {
|
|
| 863 |
+ fclose(file); |
|
| 864 |
+ return false; |
|
| 865 |
+ } |
|
| 866 |
+ } |
|
| 867 |
+ i += 8; |
|
| 868 |
+ } |
|
| 869 |
+ fclose(file); |
|
| 870 |
+ } |
|
| 871 |
+ return true; |
|
| 872 |
+} |
|
| 873 |
+ |
|
| 874 |
+bool CPUWriteBatteryFile(const char *fileName) |
|
| 875 |
+{
|
|
| 876 |
+ if(gbaSaveType == 0) {
|
|
| 877 |
+ if(eepromInUse) |
|
| 878 |
+ gbaSaveType = 3; |
|
| 879 |
+ else switch(saveType) {
|
|
| 880 |
+ case 1: |
|
| 881 |
+ gbaSaveType = 1; |
|
| 882 |
+ break; |
|
| 883 |
+ case 2: |
|
| 884 |
+ gbaSaveType = 2; |
|
| 885 |
+ break; |
|
| 886 |
+ } |
|
| 887 |
+ } |
|
| 888 |
+ |
|
| 889 |
+ if((gbaSaveType) && (gbaSaveType!=5)) {
|
|
| 890 |
+ FILE *file = fopen(fileName, "wb"); |
|
| 891 |
+ |
|
| 892 |
+ if(!file) {
|
|
| 893 |
+ systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
|
|
| 894 |
+ fileName); |
|
| 895 |
+ return false; |
|
| 896 |
+ } |
|
| 897 |
+ |
|
| 898 |
+ // only save if Flash/Sram in use or EEprom in use |
|
| 899 |
+ if(gbaSaveType != 3) {
|
|
| 900 |
+ if(gbaSaveType == 2) {
|
|
| 901 |
+ if(fwrite(flashSaveMemory, 1, flashSize, file) != (size_t)flashSize) {
|
|
| 902 |
+ fclose(file); |
|
| 903 |
+ return false; |
|
| 904 |
+ } |
|
| 905 |
+ } else {
|
|
| 906 |
+ if(fwrite(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
|
|
| 907 |
+ fclose(file); |
|
| 908 |
+ return false; |
|
| 909 |
+ } |
|
| 910 |
+ } |
|
| 911 |
+ } else {
|
|
| 912 |
+ if(fwrite(eepromData, 1, eepromSize, file) != (size_t)eepromSize) {
|
|
| 913 |
+ fclose(file); |
|
| 914 |
+ return false; |
|
| 915 |
+ } |
|
| 916 |
+ } |
|
| 917 |
+ fclose(file); |
|
| 918 |
+ } |
|
| 919 |
+ return true; |
|
| 920 |
+} |
|
| 921 |
+ |
|
| 922 |
+bool CPUReadGSASnapshot(const char *fileName) |
|
| 923 |
+{
|
|
| 924 |
+ int i; |
|
| 925 |
+ FILE *file = fopen(fileName, "rb"); |
|
| 926 |
+ |
|
| 927 |
+ if(!file) {
|
|
| 928 |
+ systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
|
|
| 929 |
+ return false; |
|
| 930 |
+ } |
|
| 931 |
+ |
|
| 932 |
+ // check file size to know what we should read |
|
| 933 |
+ fseek(file, 0, SEEK_END); |
|
| 934 |
+ |
|
| 935 |
+ // long size = ftell(file); |
|
| 936 |
+ fseek(file, 0x0, SEEK_SET); |
|
| 937 |
+ fread(&i, 1, 4, file); |
|
| 938 |
+ fseek(file, i, SEEK_CUR); // Skip SharkPortSave |
|
| 939 |
+ fseek(file, 4, SEEK_CUR); // skip some sort of flag |
|
| 940 |
+ fread(&i, 1, 4, file); // name length |
|
| 941 |
+ fseek(file, i, SEEK_CUR); // skip name |
|
| 942 |
+ fread(&i, 1, 4, file); // desc length |
|
| 943 |
+ fseek(file, i, SEEK_CUR); // skip desc |
|
| 944 |
+ fread(&i, 1, 4, file); // notes length |
|
| 945 |
+ fseek(file, i, SEEK_CUR); // skip notes |
|
| 946 |
+ int saveSize; |
|
| 947 |
+ fread(&saveSize, 1, 4, file); // read length |
|
| 948 |
+ saveSize -= 0x1c; // remove header size |
|
| 949 |
+ char buffer[17]; |
|
| 950 |
+ char buffer2[17]; |
|
| 951 |
+ fread(buffer, 1, 16, file); |
|
| 952 |
+ buffer[16] = 0; |
|
| 953 |
+ for(i = 0; i < 16; i++) |
|
| 954 |
+ if(buffer[i] < 32) |
|
| 955 |
+ buffer[i] = 32; |
|
| 956 |
+ memcpy(buffer2, &rom[0xa0], 16); |
|
| 957 |
+ buffer2[16] = 0; |
|
| 958 |
+ for(i = 0; i < 16; i++) |
|
| 959 |
+ if(buffer2[i] < 32) |
|
| 960 |
+ buffer2[i] = 32; |
|
| 961 |
+ if(memcmp(buffer, buffer2, 16)) {
|
|
| 962 |
+ systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR, |
|
| 963 |
+ N_("Cannot import snapshot for %s. Current game is %s"),
|
|
| 964 |
+ buffer, |
|
| 965 |
+ buffer2); |
|
| 966 |
+ fclose(file); |
|
| 967 |
+ return false; |
|
| 968 |
+ } |
|
| 969 |
+ fseek(file, 12, SEEK_CUR); // skip some flags |
|
| 970 |
+ if(saveSize >= 65536) {
|
|
| 971 |
+ if(fread(flashSaveMemory, 1, saveSize, file) != (size_t)saveSize) {
|
|
| 972 |
+ fclose(file); |
|
| 973 |
+ return false; |
|
| 974 |
+ } |
|
| 975 |
+ } else {
|
|
| 976 |
+ systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE, |
|
| 977 |
+ N_("Unsupported snapshot file %s"),
|
|
| 978 |
+ fileName); |
|
| 979 |
+ fclose(file); |
|
| 980 |
+ return false; |
|
| 981 |
+ } |
|
| 982 |
+ fclose(file); |
|
| 983 |
+ CPUReset(); |
|
| 984 |
+ return true; |
|
| 985 |
+} |
|
| 986 |
+ |
|
| 987 |
+bool CPUReadGSASPSnapshot(const char *fileName) |
|
| 988 |
+{
|
|
| 989 |
+ const char gsvfooter[] = "xV4\x12"; |
|
| 990 |
+ const size_t namepos=0x0c, namesz=12; |
|
| 991 |
+ const size_t footerpos=0x42c, footersz=4; |
|
| 992 |
+ |
|
| 993 |
+ char footer[footersz+1], romname[namesz+1], savename[namesz+1];; |
|
| 994 |
+ FILE *file = fopen(fileName, "rb"); |
|
| 995 |
+ |
|
| 996 |
+ if(!file) {
|
|
| 997 |
+ systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
|
|
| 998 |
+ return false; |
|
| 999 |
+ } |
|
| 1000 |
+ |
|
| 1001 |
+ // read save name |
|
| 1002 |
+ fseek(file, namepos, SEEK_SET); |
|
| 1003 |
+ fread(savename, 1, namesz, file); |
|
| 1004 |
+ savename[namesz] = 0; |
|
| 1005 |
+ |
|
| 1006 |
+ memcpy(romname, &rom[0xa0], namesz); |
|
| 1007 |
+ romname[namesz] = 0; |
|
| 1008 |
+ |
|
| 1009 |
+ if(memcmp(romname, savename, namesz)) {
|
|
| 1010 |
+ systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR, |
|
| 1011 |
+ N_("Cannot import snapshot for %s. Current game is %s"),
|
|
| 1012 |
+ savename, |
|
| 1013 |
+ romname); |
|
| 1014 |
+ fclose(file); |
|
| 1015 |
+ return false; |
|
| 1016 |
+ } |
|
| 1017 |
+ |
|
| 1018 |
+ // read footer tag |
|
| 1019 |
+ fseek(file, footerpos, SEEK_SET); |
|
| 1020 |
+ fread(footer, 1, footersz, file); |
|
| 1021 |
+ footer[footersz] = 0; |
|
| 1022 |
+ |
|
| 1023 |
+ if(memcmp(footer, gsvfooter, footersz)) {
|
|
| 1024 |
+ systemMessage(0, |
|
| 1025 |
+ N_("Unsupported snapshot file %s. Footer '%s' at %u should be '%s'"),
|
|
| 1026 |
+ fileName, |
|
| 1027 |
+ footer, |
|
| 1028 |
+ footerpos, |
|
| 1029 |
+ gsvfooter); |
|
| 1030 |
+ fclose(file); |
|
| 1031 |
+ return false; |
|
| 1032 |
+ } |
|
| 1033 |
+ |
|
| 1034 |
+ // Read up to 128k save |
|
| 1035 |
+ fread(flashSaveMemory, 1, FLASH_128K_SZ, file); |
|
| 1036 |
+ |
|
| 1037 |
+ fclose(file); |
|
| 1038 |
+ CPUReset(); |
|
| 1039 |
+ return true; |
|
| 1040 |
+} |
|
| 1041 |
+ |
|
| 1042 |
+ |
|
| 1043 |
+bool CPUWriteGSASnapshot(const char *fileName, |
|
| 1044 |
+ const char *title, |
|
| 1045 |
+ const char *desc, |
|
| 1046 |
+ const char *notes) |
|
| 1047 |
+{
|
|
| 1048 |
+ FILE *file = fopen(fileName, "wb"); |
|
| 1049 |
+ |
|
| 1050 |
+ if(!file) {
|
|
| 1051 |
+ systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
|
|
| 1052 |
+ return false; |
|
| 1053 |
+ } |
|
| 1054 |
+ |
|
| 1055 |
+ u8 buffer[17]; |
|
| 1056 |
+ |
|
| 1057 |
+ utilPutDword(buffer, 0x0d); // SharkPortSave length |
|
| 1058 |
+ fwrite(buffer, 1, 4, file); |
|
| 1059 |
+ fwrite("SharkPortSave", 1, 0x0d, file);
|
|
| 1060 |
+ utilPutDword(buffer, 0x000f0000); |
|
| 1061 |
+ fwrite(buffer, 1, 4, file); // save type 0x000f0000 = GBA save |
|
| 1062 |
+ utilPutDword(buffer, (u32)strlen(title)); |
|
| 1063 |
+ fwrite(buffer, 1, 4, file); // title length |
|
| 1064 |
+ fwrite(title, 1, strlen(title), file); |
|
| 1065 |
+ utilPutDword(buffer, (u32)strlen(desc)); |
|
| 1066 |
+ fwrite(buffer, 1, 4, file); // desc length |
|
| 1067 |
+ fwrite(desc, 1, strlen(desc), file); |
|
| 1068 |
+ utilPutDword(buffer, (u32)strlen(notes)); |
|
| 1069 |
+ fwrite(buffer, 1, 4, file); // notes length |
|
| 1070 |
+ fwrite(notes, 1, strlen(notes), file); |
|
| 1071 |
+ int saveSize = 0x10000; |
|
| 1072 |
+ if(gbaSaveType == 2) |
|
| 1073 |
+ saveSize = flashSize; |
|
| 1074 |
+ int totalSize = saveSize + 0x1c; |
|
| 1075 |
+ |
|
| 1076 |
+ utilPutDword(buffer, totalSize); // length of remainder of save - CRC |
|
| 1077 |
+ fwrite(buffer, 1, 4, file); |
|
| 1078 |
+ |
|
| 1079 |
+ char *temp = new char[0x2001c]; |
|
| 1080 |
+ memset(temp, 0, 28); |
|
| 1081 |
+ memcpy(temp, &rom[0xa0], 16); // copy internal name |
|
| 1082 |
+ temp[0x10] = rom[0xbe]; // reserved area (old checksum) |
|
| 1083 |
+ temp[0x11] = rom[0xbf]; // reserved area (old checksum) |
|
| 1084 |
+ temp[0x12] = rom[0xbd]; // complement check |
|
| 1085 |
+ temp[0x13] = rom[0xb0]; // maker |
|
| 1086 |
+ temp[0x14] = 1; // 1 save ? |
|
| 1087 |
+ memcpy(&temp[0x1c], flashSaveMemory, saveSize); // copy save |
|
| 1088 |
+ fwrite(temp, 1, totalSize, file); // write save + header |
|
| 1089 |
+ u32 crc = 0; |
|
| 1090 |
+ |
|
| 1091 |
+ for(int i = 0; i < totalSize; i++) {
|
|
| 1092 |
+ crc += ((u32)temp[i] << (crc % 0x18)); |
|
| 1093 |
+ } |
|
| 1094 |
+ |
|
| 1095 |
+ utilPutDword(buffer, crc); |
|
| 1096 |
+ fwrite(buffer, 1, 4, file); // CRC? |
|
| 1097 |
+ |
|
| 1098 |
+ fclose(file); |
|
| 1099 |
+ delete [] temp; |
|
| 1100 |
+ return true; |
|
| 1101 |
+} |
|
| 1102 |
+ |
|
| 1103 |
+bool CPUImportEepromFile(const char *fileName) |
|
| 1104 |
+{
|
|
| 1105 |
+ FILE *file = fopen(fileName, "rb"); |
|
| 1106 |
+ |
|
| 1107 |
+ if(!file) |
|
| 1108 |
+ return false; |
|
| 1109 |
+ |
|
| 1110 |
+ // check file size to know what we should read |
|
| 1111 |
+ fseek(file, 0, SEEK_END); |
|
| 1112 |
+ |
|
| 1113 |
+ long size = ftell(file); |
|
| 1114 |
+ fseek(file, 0, SEEK_SET); |
|
| 1115 |
+ if(size == 512 || size == 0x2000) {
|
|
| 1116 |
+ if(fread(eepromData, 1, size, file) != (size_t)size) {
|
|
| 1117 |
+ fclose(file); |
|
| 1118 |
+ return false; |
|
| 1119 |
+ } |
|
| 1120 |
+ for(int i = 0; i < size;) {
|
|
| 1121 |
+ u8 tmp = eepromData[i]; |
|
| 1122 |
+ eepromData[i] = eepromData[7-i]; |
|
| 1123 |
+ eepromData[7-i] = tmp; |
|
| 1124 |
+ i++; |
|
| 1125 |
+ tmp = eepromData[i]; |
|
| 1126 |
+ eepromData[i] = eepromData[7-i]; |
|
| 1127 |
+ eepromData[7-i] = tmp; |
|
| 1128 |
+ i++; |
|
| 1129 |
+ tmp = eepromData[i]; |
|
| 1130 |
+ eepromData[i] = eepromData[7-i]; |
|
| 1131 |
+ eepromData[7-i] = tmp; |
|
| 1132 |
+ i++; |
|
| 1133 |
+ tmp = eepromData[i]; |
|
| 1134 |
+ eepromData[i] = eepromData[7-i]; |
|
| 1135 |
+ eepromData[7-i] = tmp; |
|
| 1136 |
+ i++; |
|
| 1137 |
+ i += 4; |
|
| 1138 |
+ } |
|
| 1139 |
+ } else {
|
|
| 1140 |
+ fclose(file); |
|
| 1141 |
+ return false; |
|
| 1142 |
+ } |
|
| 1143 |
+ fclose(file); |
|
| 1144 |
+ return true; |
|
| 1145 |
+} |
|
| 1146 |
+ |
|
| 1147 |
+bool CPUReadBatteryFile(const char *fileName) |
|
| 1148 |
+{
|
|
| 1149 |
+ FILE *file = fopen(fileName, "rb"); |
|
| 1150 |
+ |
|
| 1151 |
+ if(!file) |
|
| 1152 |
+ return false; |
|
| 1153 |
+ |
|
| 1154 |
+ // check file size to know what we should read |
|
| 1155 |
+ fseek(file, 0, SEEK_END); |
|
| 1156 |
+ |
|
| 1157 |
+ long size = ftell(file); |
|
| 1158 |
+ fseek(file, 0, SEEK_SET); |
|
| 1159 |
+ systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 1160 |
+ |
|
| 1161 |
+ if(size == 512 || size == 0x2000) {
|
|
| 1162 |
+ if(fread(eepromData, 1, size, file) != (size_t)size) {
|
|
| 1163 |
+ fclose(file); |
|
| 1164 |
+ return false; |
|
| 1165 |
+ } |
|
| 1166 |
+ } else {
|
|
| 1167 |
+ if(size == 0x20000) {
|
|
| 1168 |
+ if(fread(flashSaveMemory, 1, 0x20000, file) != 0x20000) {
|
|
| 1169 |
+ fclose(file); |
|
| 1170 |
+ return false; |
|
| 1171 |
+ } |
|
| 1172 |
+ flashSetSize(0x20000); |
|
| 1173 |
+ } else {
|
|
| 1174 |
+ if(fread(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
|
|
| 1175 |
+ fclose(file); |
|
| 1176 |
+ return false; |
|
| 1177 |
+ } |
|
| 1178 |
+ flashSetSize(0x10000); |
|
| 1179 |
+ } |
|
| 1180 |
+ } |
|
| 1181 |
+ fclose(file); |
|
| 1182 |
+ return true; |
|
| 1183 |
+} |
|
| 1184 |
+ |
|
| 1185 |
+bool CPUWritePNGFile(const char *fileName) |
|
| 1186 |
+{
|
|
| 1187 |
+ return utilWritePNGFile(fileName, 240, 160, pix); |
|
| 1188 |
+} |
|
| 1189 |
+ |
|
| 1190 |
+bool CPUWriteBMPFile(const char *fileName) |
|
| 1191 |
+{
|
|
| 1192 |
+ return utilWriteBMPFile(fileName, 240, 160, pix); |
|
| 1193 |
+}*/ |
|
| 1194 |
+ |
|
| 1195 |
+bool CPUIsZipFile(const char * file) |
|
| 1196 |
+{
|
|
| 1197 |
+ if(strlen(file) > 4) {
|
|
| 1198 |
+ const char * p = strrchr(file,'.'); |
|
| 1199 |
+ |
|
| 1200 |
+ if(p != NULL) {
|
|
| 1201 |
+ if(_stricmp(p, ".zip") == 0) |
|
| 1202 |
+ return true; |
|
| 1203 |
+ } |
|
| 1204 |
+ } |
|
| 1205 |
+ |
|
| 1206 |
+ return false; |
|
| 1207 |
+} |
|
| 1208 |
+ |
|
| 1209 |
+bool CPUIsGBAImage(const char * file) |
|
| 1210 |
+{
|
|
| 1211 |
+ cpuIsMultiBoot = false; |
|
| 1212 |
+ if(strlen(file) > 4) {
|
|
| 1213 |
+ const char * p = strrchr(file,'.'); |
|
| 1214 |
+ |
|
| 1215 |
+ if(p != NULL) {
|
|
| 1216 |
+ if(_stricmp(p, ".gba") == 0) |
|
| 1217 |
+ return true; |
|
| 1218 |
+ if(_stricmp(p, ".agb") == 0) |
|
| 1219 |
+ return true; |
|
| 1220 |
+ if(_stricmp(p, ".bin") == 0) |
|
| 1221 |
+ return true; |
|
| 1222 |
+ if(_stricmp(p, ".elf") == 0) |
|
| 1223 |
+ return true; |
|
| 1224 |
+ if(_stricmp(p, ".mb") == 0) {
|
|
| 1225 |
+ cpuIsMultiBoot = true; |
|
| 1226 |
+ return true; |
|
| 1227 |
+ } |
|
| 1228 |
+ } |
|
| 1229 |
+ } |
|
| 1230 |
+ |
|
| 1231 |
+ return false; |
|
| 1232 |
+} |
|
| 1233 |
+ |
|
| 1234 |
+bool CPUIsGBABios(const char * file) |
|
| 1235 |
+{
|
|
| 1236 |
+ if(strlen(file) > 4) {
|
|
| 1237 |
+ const char * p = strrchr(file,'.'); |
|
| 1238 |
+ |
|
| 1239 |
+ if(p != NULL) {
|
|
| 1240 |
+ if(_stricmp(p, ".gba") == 0) |
|
| 1241 |
+ return true; |
|
| 1242 |
+ if(_stricmp(p, ".agb") == 0) |
|
| 1243 |
+ return true; |
|
| 1244 |
+ if(_stricmp(p, ".bin") == 0) |
|
| 1245 |
+ return true; |
|
| 1246 |
+ if(_stricmp(p, ".bios") == 0) |
|
| 1247 |
+ return true; |
|
| 1248 |
+ if(_stricmp(p, ".rom") == 0) |
|
| 1249 |
+ return true; |
|
| 1250 |
+ } |
|
| 1251 |
+ } |
|
| 1252 |
+ |
|
| 1253 |
+ return false; |
|
| 1254 |
+} |
|
| 1255 |
+ |
|
| 1256 |
+bool CPUIsELF(const char *file) |
|
| 1257 |
+{
|
|
| 1258 |
+ if(file == NULL) |
|
| 1259 |
+ return false; |
|
| 1260 |
+ |
|
| 1261 |
+ if(strlen(file) > 4) {
|
|
| 1262 |
+ const char * p = strrchr(file,'.'); |
|
| 1263 |
+ |
|
| 1264 |
+ if(p != NULL) {
|
|
| 1265 |
+ if(_stricmp(p, ".elf") == 0) |
|
| 1266 |
+ return true; |
|
| 1267 |
+ } |
|
| 1268 |
+ } |
|
| 1269 |
+ return false; |
|
| 1270 |
+} |
|
| 1271 |
+ |
|
| 1272 |
+void CPUCleanUp() |
|
| 1273 |
+{
|
|
| 1274 |
+#ifdef PROFILING |
|
| 1275 |
+ if(profilingTicksReload) {
|
|
| 1276 |
+ profCleanup(); |
|
| 1277 |
+ } |
|
| 1278 |
+#endif |
|
| 1279 |
+ |
|
| 1280 |
+ if(rom != NULL) {
|
|
| 1281 |
+ free(rom); |
|
| 1282 |
+ rom = NULL; |
|
| 1283 |
+ } |
|
| 1284 |
+ |
|
| 1285 |
+ if(vram != NULL) {
|
|
| 1286 |
+ free(vram); |
|
| 1287 |
+ vram = NULL; |
|
| 1288 |
+ } |
|
| 1289 |
+ |
|
| 1290 |
+ if(paletteRAM != NULL) {
|
|
| 1291 |
+ free(paletteRAM); |
|
| 1292 |
+ paletteRAM = NULL; |
|
| 1293 |
+ } |
|
| 1294 |
+ |
|
| 1295 |
+ if(internalRAM != NULL) {
|
|
| 1296 |
+ free(internalRAM); |
|
| 1297 |
+ internalRAM = NULL; |
|
| 1298 |
+ } |
|
| 1299 |
+ |
|
| 1300 |
+ if(workRAM != NULL) {
|
|
| 1301 |
+ free(workRAM); |
|
| 1302 |
+ workRAM = NULL; |
|
| 1303 |
+ } |
|
| 1304 |
+ |
|
| 1305 |
+ if(bios != NULL) {
|
|
| 1306 |
+ free(bios); |
|
| 1307 |
+ bios = NULL; |
|
| 1308 |
+ } |
|
| 1309 |
+ |
|
| 1310 |
+ if(pix != NULL) {
|
|
| 1311 |
+ free(pix); |
|
| 1312 |
+ pix = NULL; |
|
| 1313 |
+ } |
|
| 1314 |
+ |
|
| 1315 |
+ if(oam != NULL) {
|
|
| 1316 |
+ free(oam); |
|
| 1317 |
+ oam = NULL; |
|
| 1318 |
+ } |
|
| 1319 |
+ |
|
| 1320 |
+ if(ioMem != NULL) {
|
|
| 1321 |
+ free(ioMem); |
|
| 1322 |
+ ioMem = NULL; |
|
| 1323 |
+ } |
|
| 1324 |
+ |
|
| 1325 |
+#ifndef NO_DEBUGGER |
|
| 1326 |
+ elfCleanUp(); |
|
| 1327 |
+#endif //NO_DEBUGGER |
|
| 1328 |
+ |
|
| 1329 |
+ //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 1330 |
+ |
|
| 1331 |
+ //emulating = 0; |
|
| 1332 |
+} |
|
| 1333 |
+ |
|
| 1334 |
+int CPULoadRom(const char *szFile) |
|
| 1335 |
+{
|
|
| 1336 |
+ romSize = 0x2000000; |
|
| 1337 |
+ if(rom != NULL) {
|
|
| 1338 |
+ CPUCleanUp(); |
|
| 1339 |
+ } |
|
| 1340 |
+ |
|
| 1341 |
+ //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 1342 |
+ |
|
| 1343 |
+ rom = (u8 *)malloc(0x2000000); |
|
| 1344 |
+ if(rom == NULL) {
|
|
| 1345 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1346 |
+ "ROM");*/ |
|
| 1347 |
+ return 0; |
|
| 1348 |
+ } |
|
| 1349 |
+ workRAM = (u8 *)calloc(1, 0x40000); |
|
| 1350 |
+ if(workRAM == NULL) {
|
|
| 1351 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1352 |
+ "WRAM");*/ |
|
| 1353 |
+ return 0; |
|
| 1354 |
+ } |
|
| 1355 |
+ |
|
| 1356 |
+ u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom; |
|
| 1357 |
+ |
|
| 1358 |
+#ifndef NO_DEBUGGER |
|
| 1359 |
+ if(CPUIsELF(szFile)) {
|
|
| 1360 |
+ FILE *f = fopen(szFile, "rb"); |
|
| 1361 |
+ if(!f) {
|
|
| 1362 |
+ systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"),
|
|
| 1363 |
+ szFile); |
|
| 1364 |
+ free(rom); |
|
| 1365 |
+ rom = NULL; |
|
| 1366 |
+ free(workRAM); |
|
| 1367 |
+ workRAM = NULL; |
|
| 1368 |
+ return 0; |
|
| 1369 |
+ } |
|
| 1370 |
+ bool res = elfRead(szFile, romSize, f); |
|
| 1371 |
+ if(!res || romSize == 0) {
|
|
| 1372 |
+ free(rom); |
|
| 1373 |
+ rom = NULL; |
|
| 1374 |
+ free(workRAM); |
|
| 1375 |
+ workRAM = NULL; |
|
| 1376 |
+ elfCleanUp(); |
|
| 1377 |
+ return 0; |
|
| 1378 |
+ } |
|
| 1379 |
+ } else |
|
| 1380 |
+#endif //NO_DEBUGGER |
|
| 1381 |
+ /*if(szFile!=NULL) |
|
| 1382 |
+ {
|
|
| 1383 |
+ if(!utilLoad(szFile, |
|
| 1384 |
+ utilIsGBAImage, |
|
| 1385 |
+ whereToLoad, |
|
| 1386 |
+ romSize)) {
|
|
| 1387 |
+ free(rom); |
|
| 1388 |
+ rom = NULL; |
|
| 1389 |
+ free(workRAM); |
|
| 1390 |
+ workRAM = NULL; |
|
| 1391 |
+ return 0; |
|
| 1392 |
+ } |
|
| 1393 |
+ }*/ |
|
| 1394 |
+ if (cpuIsMultiBoot) |
|
| 1395 |
+ mapgsf(workRAM,0x40000,romSize); |
|
| 1396 |
+ else |
|
| 1397 |
+ mapgsf(rom, 0x2000000,romSize); |
|
| 1398 |
+ |
|
| 1399 |
+ u16 *temp = (u16 *)(rom+((romSize+1)&~1)); |
|
| 1400 |
+ int i; |
|
| 1401 |
+ for(i = (romSize+1)&~1; i < 0x2000000; i+=2) {
|
|
| 1402 |
+ WRITE16LE(temp, (i >> 1) & 0xFFFF); |
|
| 1403 |
+ temp++; |
|
| 1404 |
+ } |
|
| 1405 |
+ |
|
| 1406 |
+ bios = (u8 *)calloc(1,0x4000); |
|
| 1407 |
+ if(bios == NULL) {
|
|
| 1408 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1409 |
+ "BIOS");*/ |
|
| 1410 |
+ CPUCleanUp(); |
|
| 1411 |
+ return 0; |
|
| 1412 |
+ } |
|
| 1413 |
+ internalRAM = (u8 *)calloc(1,0x8000); |
|
| 1414 |
+ if(internalRAM == NULL) {
|
|
| 1415 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1416 |
+ "IRAM");*/ |
|
| 1417 |
+ CPUCleanUp(); |
|
| 1418 |
+ return 0; |
|
| 1419 |
+ } |
|
| 1420 |
+ paletteRAM = (u8 *)calloc(1,0x400); |
|
| 1421 |
+ if(paletteRAM == NULL) {
|
|
| 1422 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1423 |
+ "PRAM");*/ |
|
| 1424 |
+ CPUCleanUp(); |
|
| 1425 |
+ return 0; |
|
| 1426 |
+ } |
|
| 1427 |
+ vram = (u8 *)calloc(1, 0x20000); |
|
| 1428 |
+ if(vram == NULL) {
|
|
| 1429 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1430 |
+ "VRAM");*/ |
|
| 1431 |
+ CPUCleanUp(); |
|
| 1432 |
+ return 0; |
|
| 1433 |
+ } |
|
| 1434 |
+ oam = (u8 *)calloc(1, 0x400); |
|
| 1435 |
+ if(oam == NULL) {
|
|
| 1436 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1437 |
+ "OAM");*/ |
|
| 1438 |
+ CPUCleanUp(); |
|
| 1439 |
+ return 0; |
|
| 1440 |
+ } |
|
| 1441 |
+ pix = (u8 *)calloc(1, 4 * 241 * 162); |
|
| 1442 |
+ if(pix == NULL) {
|
|
| 1443 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1444 |
+ "PIX");*/ |
|
| 1445 |
+ CPUCleanUp(); |
|
| 1446 |
+ return 0; |
|
| 1447 |
+ } |
|
| 1448 |
+ ioMem = (u8 *)calloc(1, 0x400); |
|
| 1449 |
+ if(ioMem == NULL) {
|
|
| 1450 |
+ /*systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
|
|
| 1451 |
+ "IO");*/ |
|
| 1452 |
+ CPUCleanUp(); |
|
| 1453 |
+ return 0; |
|
| 1454 |
+ } |
|
| 1455 |
+ |
|
| 1456 |
+ //flashInit(); |
|
| 1457 |
+ //eepromInit(); |
|
| 1458 |
+ |
|
| 1459 |
+ //CPUUpdateRenderBuffers(true); |
|
| 1460 |
+ |
|
| 1461 |
+ return romSize; |
|
| 1462 |
+} |
|
| 1463 |
+ |
|
| 1464 |
+void doMirroring (bool b) |
|
| 1465 |
+{
|
|
| 1466 |
+ u32 mirroredRomSize = (((romSize)>>20) & 0x3F)<<20; |
|
| 1467 |
+ u32 mirroredRomAddress = romSize; |
|
| 1468 |
+ if ((mirroredRomSize <=0x800000) && (b)) |
|
| 1469 |
+ {
|
|
| 1470 |
+ mirroredRomAddress = mirroredRomSize; |
|
| 1471 |
+ if (mirroredRomSize==0) |
|
| 1472 |
+ mirroredRomSize=0x100000; |
|
| 1473 |
+ while (mirroredRomAddress<0x01000000) |
|
| 1474 |
+ {
|
|
| 1475 |
+ memcpy ((u16 *)(rom+mirroredRomAddress), (u16 *)(rom), mirroredRomSize); |
|
| 1476 |
+ mirroredRomAddress+=mirroredRomSize; |
|
| 1477 |
+ } |
|
| 1478 |
+ } |
|
| 1479 |
+} |
|
| 1480 |
+ |
|
| 1481 |
+/*void CPUUpdateRender() |
|
| 1482 |
+{
|
|
| 1483 |
+ switch(DISPCNT & 7) {
|
|
| 1484 |
+ case 0: |
|
| 1485 |
+ if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1486 |
+ cpuDisableSfx) |
|
| 1487 |
+ renderLine = mode0RenderLine; |
|
| 1488 |
+ else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1489 |
+ renderLine = mode0RenderLineNoWindow; |
|
| 1490 |
+ else |
|
| 1491 |
+ renderLine = mode0RenderLineAll; |
|
| 1492 |
+ break; |
|
| 1493 |
+ case 1: |
|
| 1494 |
+ if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1495 |
+ cpuDisableSfx) |
|
| 1496 |
+ renderLine = mode1RenderLine; |
|
| 1497 |
+ else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1498 |
+ renderLine = mode1RenderLineNoWindow; |
|
| 1499 |
+ else |
|
| 1500 |
+ renderLine = mode1RenderLineAll; |
|
| 1501 |
+ break; |
|
| 1502 |
+ case 2: |
|
| 1503 |
+ if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1504 |
+ cpuDisableSfx) |
|
| 1505 |
+ renderLine = mode2RenderLine; |
|
| 1506 |
+ else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1507 |
+ renderLine = mode2RenderLineNoWindow; |
|
| 1508 |
+ else |
|
| 1509 |
+ renderLine = mode2RenderLineAll; |
|
| 1510 |
+ break; |
|
| 1511 |
+ case 3: |
|
| 1512 |
+ if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1513 |
+ cpuDisableSfx) |
|
| 1514 |
+ renderLine = mode3RenderLine; |
|
| 1515 |
+ else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1516 |
+ renderLine = mode3RenderLineNoWindow; |
|
| 1517 |
+ else |
|
| 1518 |
+ renderLine = mode3RenderLineAll; |
|
| 1519 |
+ break; |
|
| 1520 |
+ case 4: |
|
| 1521 |
+ if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1522 |
+ cpuDisableSfx) |
|
| 1523 |
+ renderLine = mode4RenderLine; |
|
| 1524 |
+ else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1525 |
+ renderLine = mode4RenderLineNoWindow; |
|
| 1526 |
+ else |
|
| 1527 |
+ renderLine = mode4RenderLineAll; |
|
| 1528 |
+ break; |
|
| 1529 |
+ case 5: |
|
| 1530 |
+ if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || |
|
| 1531 |
+ cpuDisableSfx) |
|
| 1532 |
+ renderLine = mode5RenderLine; |
|
| 1533 |
+ else if(fxOn && !windowOn && !(layerEnable & 0x8000)) |
|
| 1534 |
+ renderLine = mode5RenderLineNoWindow; |
|
| 1535 |
+ else |
|
| 1536 |
+ renderLine = mode5RenderLineAll; |
|
| 1537 |
+ default: |
|
| 1538 |
+ break; |
|
| 1539 |
+ } |
|
| 1540 |
+}*/ |
|
| 1541 |
+ |
|
| 1542 |
+void CPUUpdateCPSR() |
|
| 1543 |
+{
|
|
| 1544 |
+ u32 CPSR = reg[16].I & 0x40; |
|
| 1545 |
+ if(N_FLAG) |
|
| 1546 |
+ CPSR |= 0x80000000; |
|
| 1547 |
+ if(Z_FLAG) |
|
| 1548 |
+ CPSR |= 0x40000000; |
|
| 1549 |
+ if(C_FLAG) |
|
| 1550 |
+ CPSR |= 0x20000000; |
|
| 1551 |
+ if(V_FLAG) |
|
| 1552 |
+ CPSR |= 0x10000000; |
|
| 1553 |
+ if(!armState) |
|
| 1554 |
+ CPSR |= 0x00000020; |
|
| 1555 |
+ if(!armIrqEnable) |
|
| 1556 |
+ CPSR |= 0x80; |
|
| 1557 |
+ CPSR |= (armMode & 0x1F); |
|
| 1558 |
+ reg[16].I = CPSR; |
|
| 1559 |
+} |
|
| 1560 |
+ |
|
| 1561 |
+void CPUUpdateFlags(bool breakLoop) |
|
| 1562 |
+{
|
|
| 1563 |
+ u32 CPSR = reg[16].I; |
|
| 1564 |
+ |
|
| 1565 |
+ N_FLAG = (CPSR & 0x80000000) ? true: false; |
|
| 1566 |
+ Z_FLAG = (CPSR & 0x40000000) ? true: false; |
|
| 1567 |
+ C_FLAG = (CPSR & 0x20000000) ? true: false; |
|
| 1568 |
+ V_FLAG = (CPSR & 0x10000000) ? true: false; |
|
| 1569 |
+ armState = (CPSR & 0x20) ? false : true; |
|
| 1570 |
+ armIrqEnable = (CPSR & 0x80) ? false : true; |
|
| 1571 |
+ if(breakLoop) {
|
|
| 1572 |
+ if (armIrqEnable && (IF & IE) && (IME & 1)) |
|
| 1573 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1574 |
+ } |
|
| 1575 |
+} |
|
| 1576 |
+ |
|
| 1577 |
+void CPUUpdateFlags() |
|
| 1578 |
+{
|
|
| 1579 |
+ CPUUpdateFlags(true); |
|
| 1580 |
+} |
|
| 1581 |
+ |
|
| 1582 |
+#ifdef WORDS_BIGENDIAN |
|
| 1583 |
+static void CPUSwap(volatile u32 *a, volatile u32 *b) |
|
| 1584 |
+{
|
|
| 1585 |
+ volatile u32 c = *b; |
|
| 1586 |
+ *b = *a; |
|
| 1587 |
+ *a = c; |
|
| 1588 |
+} |
|
| 1589 |
+#else |
|
| 1590 |
+static void CPUSwap(u32 *a, u32 *b) |
|
| 1591 |
+{
|
|
| 1592 |
+ u32 c = *b; |
|
| 1593 |
+ *b = *a; |
|
| 1594 |
+ *a = c; |
|
| 1595 |
+} |
|
| 1596 |
+#endif |
|
| 1597 |
+ |
|
| 1598 |
+void CPUSwitchMode(int mode, bool saveState, bool breakLoop) |
|
| 1599 |
+{
|
|
| 1600 |
+ // if(armMode == mode) |
|
| 1601 |
+ // return; |
|
| 1602 |
+ |
|
| 1603 |
+ CPUUpdateCPSR(); |
|
| 1604 |
+ |
|
| 1605 |
+ switch(armMode) {
|
|
| 1606 |
+ case 0x10: |
|
| 1607 |
+ case 0x1F: |
|
| 1608 |
+ reg[R13_USR].I = reg[13].I; |
|
| 1609 |
+ reg[R14_USR].I = reg[14].I; |
|
| 1610 |
+ reg[17].I = reg[16].I; |
|
| 1611 |
+ break; |
|
| 1612 |
+ case 0x11: |
|
| 1613 |
+ CPUSwap(®[R8_FIQ].I, ®[8].I); |
|
| 1614 |
+ CPUSwap(®[R9_FIQ].I, ®[9].I); |
|
| 1615 |
+ CPUSwap(®[R10_FIQ].I, ®[10].I); |
|
| 1616 |
+ CPUSwap(®[R11_FIQ].I, ®[11].I); |
|
| 1617 |
+ CPUSwap(®[R12_FIQ].I, ®[12].I); |
|
| 1618 |
+ reg[R13_FIQ].I = reg[13].I; |
|
| 1619 |
+ reg[R14_FIQ].I = reg[14].I; |
|
| 1620 |
+ reg[SPSR_FIQ].I = reg[17].I; |
|
| 1621 |
+ break; |
|
| 1622 |
+ case 0x12: |
|
| 1623 |
+ reg[R13_IRQ].I = reg[13].I; |
|
| 1624 |
+ reg[R14_IRQ].I = reg[14].I; |
|
| 1625 |
+ reg[SPSR_IRQ].I = reg[17].I; |
|
| 1626 |
+ break; |
|
| 1627 |
+ case 0x13: |
|
| 1628 |
+ reg[R13_SVC].I = reg[13].I; |
|
| 1629 |
+ reg[R14_SVC].I = reg[14].I; |
|
| 1630 |
+ reg[SPSR_SVC].I = reg[17].I; |
|
| 1631 |
+ break; |
|
| 1632 |
+ case 0x17: |
|
| 1633 |
+ reg[R13_ABT].I = reg[13].I; |
|
| 1634 |
+ reg[R14_ABT].I = reg[14].I; |
|
| 1635 |
+ reg[SPSR_ABT].I = reg[17].I; |
|
| 1636 |
+ break; |
|
| 1637 |
+ case 0x1b: |
|
| 1638 |
+ reg[R13_UND].I = reg[13].I; |
|
| 1639 |
+ reg[R14_UND].I = reg[14].I; |
|
| 1640 |
+ reg[SPSR_UND].I = reg[17].I; |
|
| 1641 |
+ break; |
|
| 1642 |
+ } |
|
| 1643 |
+ |
|
| 1644 |
+ u32 CPSR = reg[16].I; |
|
| 1645 |
+ u32 SPSR = reg[17].I; |
|
| 1646 |
+ |
|
| 1647 |
+ switch(mode) {
|
|
| 1648 |
+ case 0x10: |
|
| 1649 |
+ case 0x1F: |
|
| 1650 |
+ reg[13].I = reg[R13_USR].I; |
|
| 1651 |
+ reg[14].I = reg[R14_USR].I; |
|
| 1652 |
+ reg[16].I = SPSR; |
|
| 1653 |
+ break; |
|
| 1654 |
+ case 0x11: |
|
| 1655 |
+ CPUSwap(®[8].I, ®[R8_FIQ].I); |
|
| 1656 |
+ CPUSwap(®[9].I, ®[R9_FIQ].I); |
|
| 1657 |
+ CPUSwap(®[10].I, ®[R10_FIQ].I); |
|
| 1658 |
+ CPUSwap(®[11].I, ®[R11_FIQ].I); |
|
| 1659 |
+ CPUSwap(®[12].I, ®[R12_FIQ].I); |
|
| 1660 |
+ reg[13].I = reg[R13_FIQ].I; |
|
| 1661 |
+ reg[14].I = reg[R14_FIQ].I; |
|
| 1662 |
+ if(saveState) |
|
| 1663 |
+ reg[17].I = CPSR; |
|
| 1664 |
+ else |
|
| 1665 |
+ reg[17].I = reg[SPSR_FIQ].I; |
|
| 1666 |
+ break; |
|
| 1667 |
+ case 0x12: |
|
| 1668 |
+ reg[13].I = reg[R13_IRQ].I; |
|
| 1669 |
+ reg[14].I = reg[R14_IRQ].I; |
|
| 1670 |
+ reg[16].I = SPSR; |
|
| 1671 |
+ if(saveState) |
|
| 1672 |
+ reg[17].I = CPSR; |
|
| 1673 |
+ else |
|
| 1674 |
+ reg[17].I = reg[SPSR_IRQ].I; |
|
| 1675 |
+ break; |
|
| 1676 |
+ case 0x13: |
|
| 1677 |
+ reg[13].I = reg[R13_SVC].I; |
|
| 1678 |
+ reg[14].I = reg[R14_SVC].I; |
|
| 1679 |
+ reg[16].I = SPSR; |
|
| 1680 |
+ if(saveState) |
|
| 1681 |
+ reg[17].I = CPSR; |
|
| 1682 |
+ else |
|
| 1683 |
+ reg[17].I = reg[SPSR_SVC].I; |
|
| 1684 |
+ break; |
|
| 1685 |
+ case 0x17: |
|
| 1686 |
+ reg[13].I = reg[R13_ABT].I; |
|
| 1687 |
+ reg[14].I = reg[R14_ABT].I; |
|
| 1688 |
+ reg[16].I = SPSR; |
|
| 1689 |
+ if(saveState) |
|
| 1690 |
+ reg[17].I = CPSR; |
|
| 1691 |
+ else |
|
| 1692 |
+ reg[17].I = reg[SPSR_ABT].I; |
|
| 1693 |
+ break; |
|
| 1694 |
+ case 0x1b: |
|
| 1695 |
+ reg[13].I = reg[R13_UND].I; |
|
| 1696 |
+ reg[14].I = reg[R14_UND].I; |
|
| 1697 |
+ reg[16].I = SPSR; |
|
| 1698 |
+ if(saveState) |
|
| 1699 |
+ reg[17].I = CPSR; |
|
| 1700 |
+ else |
|
| 1701 |
+ reg[17].I = reg[SPSR_UND].I; |
|
| 1702 |
+ break; |
|
| 1703 |
+ default: |
|
| 1704 |
+ //systemMessage(MSG_UNSUPPORTED_ARM_MODE, N_("Unsupported ARM mode %02x"), mode);
|
|
| 1705 |
+ break; |
|
| 1706 |
+ } |
|
| 1707 |
+ armMode = mode; |
|
| 1708 |
+ CPUUpdateFlags(breakLoop); |
|
| 1709 |
+ CPUUpdateCPSR(); |
|
| 1710 |
+} |
|
| 1711 |
+ |
|
| 1712 |
+void CPUSwitchMode(int mode, bool saveState) |
|
| 1713 |
+{
|
|
| 1714 |
+ CPUSwitchMode(mode, saveState, true); |
|
| 1715 |
+} |
|
| 1716 |
+ |
|
| 1717 |
+void CPUUndefinedException() |
|
| 1718 |
+{
|
|
| 1719 |
+ u32 PC = reg[15].I; |
|
| 1720 |
+ bool savedArmState = armState; |
|
| 1721 |
+ CPUSwitchMode(0x1b, true, false); |
|
| 1722 |
+ reg[14].I = PC - (savedArmState ? 4 : 2); |
|
| 1723 |
+ reg[15].I = 0x04; |
|
| 1724 |
+ armState = true; |
|
| 1725 |
+ armIrqEnable = false; |
|
| 1726 |
+ armNextPC = 0x04; |
|
| 1727 |
+ ARM_PREFETCH; |
|
| 1728 |
+ reg[15].I += 4; |
|
| 1729 |
+} |
|
| 1730 |
+ |
|
| 1731 |
+void CPUSoftwareInterrupt() |
|
| 1732 |
+{
|
|
| 1733 |
+ u32 PC = reg[15].I; |
|
| 1734 |
+ bool savedArmState = armState; |
|
| 1735 |
+ CPUSwitchMode(0x13, true, false); |
|
| 1736 |
+ reg[14].I = PC - (savedArmState ? 4 : 2); |
|
| 1737 |
+ reg[15].I = 0x08; |
|
| 1738 |
+ armState = true; |
|
| 1739 |
+ armIrqEnable = false; |
|
| 1740 |
+ armNextPC = 0x08; |
|
| 1741 |
+ ARM_PREFETCH; |
|
| 1742 |
+ reg[15].I += 4; |
|
| 1743 |
+} |
|
| 1744 |
+ |
|
| 1745 |
+void CPUSoftwareInterrupt(int comment) |
|
| 1746 |
+{
|
|
| 1747 |
+ static bool disableMessage = false; |
|
| 1748 |
+ if(armState) comment >>= 16; |
|
| 1749 |
+#ifdef BKPT_SUPPORT |
|
| 1750 |
+ if(comment == 0xff) {
|
|
| 1751 |
+ dbgOutput(NULL, reg[0].I); |
|
| 1752 |
+ return; |
|
| 1753 |
+ } |
|
| 1754 |
+#endif |
|
| 1755 |
+#ifdef PROFILING |
|
| 1756 |
+ if(comment == 0xfe) {
|
|
| 1757 |
+ profStartup(reg[0].I, reg[1].I); |
|
| 1758 |
+ return; |
|
| 1759 |
+ } |
|
| 1760 |
+ if(comment == 0xfd) {
|
|
| 1761 |
+ profControl(reg[0].I); |
|
| 1762 |
+ return; |
|
| 1763 |
+ } |
|
| 1764 |
+ if(comment == 0xfc) {
|
|
| 1765 |
+ profCleanup(); |
|
| 1766 |
+ return; |
|
| 1767 |
+ } |
|
| 1768 |
+ if(comment == 0xfb) {
|
|
| 1769 |
+ profCount(); |
|
| 1770 |
+ return; |
|
| 1771 |
+ } |
|
| 1772 |
+#endif |
|
| 1773 |
+ if(comment == 0xfa) {
|
|
| 1774 |
+ //agbPrintFlush(); |
|
| 1775 |
+ return; |
|
| 1776 |
+ } |
|
| 1777 |
+#ifdef SDL |
|
| 1778 |
+ if(comment == 0xf9) {
|
|
| 1779 |
+ emulating = 0; |
|
| 1780 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1781 |
+ cpuBreakLoop = true; |
|
| 1782 |
+ return; |
|
| 1783 |
+ } |
|
| 1784 |
+#endif |
|
| 1785 |
+ if(useBios) {
|
|
| 1786 |
+#ifdef GBA_LOGGING |
|
| 1787 |
+ if(systemVerbose & VERBOSE_SWI) {
|
|
| 1788 |
+ log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
|
| 1789 |
+ armState ? armNextPC - 4: armNextPC -2, |
|
| 1790 |
+ reg[0].I, |
|
| 1791 |
+ reg[1].I, |
|
| 1792 |
+ reg[2].I, |
|
| 1793 |
+ VCOUNT); |
|
| 1794 |
+ } |
|
| 1795 |
+#endif |
|
| 1796 |
+ CPUSoftwareInterrupt(); |
|
| 1797 |
+ return; |
|
| 1798 |
+ } |
|
| 1799 |
+ // This would be correct, but it causes problems if uncommented |
|
| 1800 |
+ // else {
|
|
| 1801 |
+ // biosProtected = 0xe3a02004; |
|
| 1802 |
+ // } |
|
| 1803 |
+ |
|
| 1804 |
+ switch(comment) {
|
|
| 1805 |
+ case 0x00: |
|
| 1806 |
+ BIOS_SoftReset(); |
|
| 1807 |
+ ARM_PREFETCH; |
|
| 1808 |
+ break; |
|
| 1809 |
+ case 0x01: |
|
| 1810 |
+ BIOS_RegisterRamReset(); |
|
| 1811 |
+ break; |
|
| 1812 |
+ case 0x02: |
|
| 1813 |
+#ifdef GBA_LOGGING |
|
| 1814 |
+ if(systemVerbose & VERBOSE_SWI) {
|
|
| 1815 |
+ log("Halt: (VCOUNT = %2d)\n",
|
|
| 1816 |
+ VCOUNT); |
|
| 1817 |
+ } |
|
| 1818 |
+#endif |
|
| 1819 |
+ holdState = true; |
|
| 1820 |
+ holdType = -1; |
|
| 1821 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1822 |
+ break; |
|
| 1823 |
+ case 0x03: |
|
| 1824 |
+#ifdef GBA_LOGGING |
|
| 1825 |
+ if(systemVerbose & VERBOSE_SWI) {
|
|
| 1826 |
+ log("Stop: (VCOUNT = %2d)\n",
|
|
| 1827 |
+ VCOUNT); |
|
| 1828 |
+ } |
|
| 1829 |
+#endif |
|
| 1830 |
+ holdState = true; |
|
| 1831 |
+ holdType = -1; |
|
| 1832 |
+ stopState = true; |
|
| 1833 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 1834 |
+ break; |
|
| 1835 |
+ case 0x04: |
|
| 1836 |
+#ifdef GBA_LOGGING |
|
| 1837 |
+ if(systemVerbose & VERBOSE_SWI) {
|
|
| 1838 |
+ log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n",
|
|
| 1839 |
+ reg[0].I, |
|
| 1840 |
+ reg[1].I, |
|
| 1841 |
+ VCOUNT); |
|
| 1842 |
+ } |
|
| 1843 |
+#endif |
|
| 1844 |
+ CPUSoftwareInterrupt(); |
|
| 1845 |
+ break; |
|
| 1846 |
+ case 0x05: |
|
| 1847 |
+#ifdef GBA_LOGGING |
|
| 1848 |
+ if(systemVerbose & VERBOSE_SWI) {
|
|
| 1849 |
+ log("VBlankIntrWait: (VCOUNT = %2d)\n",
|
|
| 1850 |
+ VCOUNT); |
|
| 1851 |
+ } |
|
| 1852 |
+#endif |
|
| 1853 |
+ CPUSoftwareInterrupt(); |
|
| 1854 |
+ break; |
|
| 1855 |
+ case 0x06: |
|
| 1856 |
+ CPUSoftwareInterrupt(); |
|
| 1857 |
+ break; |
|
| 1858 |
+ case 0x07: |
|
| 1859 |
+ CPUSoftwareInterrupt(); |
|
| 1860 |
+ break; |
|
| 1861 |
+ case 0x08: |
|
| 1862 |
+ BIOS_Sqrt(); |
|
| 1863 |
+ break; |
|
| 1864 |
+ case 0x09: |
|
| 1865 |
+ BIOS_ArcTan(); |
|
| 1866 |
+ break; |
|
| 1867 |
+ case 0x0A: |
|
| 1868 |
+ BIOS_ArcTan2(); |
|
| 1869 |
+ break; |
|
| 1870 |
+ case 0x0B: |
|
| 1871 |
+ {
|
|
| 1872 |
+ int len = (reg[2].I & 0x1FFFFF) >>1; |
|
| 1873 |
+ if (!(((reg[0].I & 0xe000000) == 0) || |
|
| 1874 |
+ ((reg[0].I + len) & 0xe000000) == 0)) |
|
| 1875 |
+ {
|
|
| 1876 |
+ if ((reg[2].I >> 24) & 1) |
|
| 1877 |
+ {
|
|
| 1878 |
+ if ((reg[2].I >> 26) & 1) |
|
| 1879 |
+ SWITicks = (7 + memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1); |
|
| 1880 |
+ else |
|
| 1881 |
+ SWITicks = (8 + memoryWait[(reg[1].I>>24) & 0xF]) * (len); |
|
| 1882 |
+ } |
|
| 1883 |
+ else |
|
| 1884 |
+ {
|
|
| 1885 |
+ if ((reg[2].I >> 26) & 1) |
|
| 1886 |
+ SWITicks = (10 + memoryWait32[(reg[0].I>>24) & 0xF] + |
|
| 1887 |
+ memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1); |
|
| 1888 |
+ else |
|
| 1889 |
+ SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] + |
|
| 1890 |
+ memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1891 |
+ } |
|
| 1892 |
+ } |
|
| 1893 |
+ } |
|
| 1894 |
+ BIOS_CpuSet(); |
|
| 1895 |
+ break; |
|
| 1896 |
+ case 0x0C: |
|
| 1897 |
+ {
|
|
| 1898 |
+ int len = (reg[2].I & 0x1FFFFF) >>5; |
|
| 1899 |
+ if (!(((reg[0].I & 0xe000000) == 0) || |
|
| 1900 |
+ ((reg[0].I + len) & 0xe000000) == 0)) |
|
| 1901 |
+ {
|
|
| 1902 |
+ if ((reg[2].I >> 24) & 1) |
|
| 1903 |
+ SWITicks = (6 + memoryWait32[(reg[1].I>>24) & 0xF] + |
|
| 1904 |
+ 7 * (memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 1)) * len; |
|
| 1905 |
+ else |
|
| 1906 |
+ SWITicks = (9 + memoryWait32[(reg[0].I>>24) & 0xF] + |
|
| 1907 |
+ memoryWait32[(reg[1].I>>24) & 0xF] + |
|
| 1908 |
+ 7 * (memoryWaitSeq32[(reg[0].I>>24) & 0xF] + |
|
| 1909 |
+ memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 2)) * len; |
|
| 1910 |
+ } |
|
| 1911 |
+ } |
|
| 1912 |
+ BIOS_CpuFastSet(); |
|
| 1913 |
+ break; |
|
| 1914 |
+ case 0x0D: |
|
| 1915 |
+ BIOS_GetBiosChecksum(); |
|
| 1916 |
+ break; |
|
| 1917 |
+ case 0x0E: |
|
| 1918 |
+ BIOS_BgAffineSet(); |
|
| 1919 |
+ break; |
|
| 1920 |
+ case 0x0F: |
|
| 1921 |
+ BIOS_ObjAffineSet(); |
|
| 1922 |
+ break; |
|
| 1923 |
+ case 0x10: |
|
| 1924 |
+ {
|
|
| 1925 |
+ int len = CPUReadHalfWord(reg[2].I); |
|
| 1926 |
+ if (!(((reg[0].I & 0xe000000) == 0) || |
|
| 1927 |
+ ((reg[0].I + len) & 0xe000000) == 0)) |
|
| 1928 |
+ SWITicks = (32 + memoryWait[(reg[0].I>>24) & 0xF]) * len; |
|
| 1929 |
+ } |
|
| 1930 |
+ BIOS_BitUnPack(); |
|
| 1931 |
+ break; |
|
| 1932 |
+ case 0x11: |
|
| 1933 |
+ {
|
|
| 1934 |
+ u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1935 |
+ if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1936 |
+ ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1937 |
+ SWITicks = (9 + memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1938 |
+ } |
|
| 1939 |
+ BIOS_LZ77UnCompWram(); |
|
| 1940 |
+ break; |
|
| 1941 |
+ case 0x12: |
|
| 1942 |
+ {
|
|
| 1943 |
+ u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1944 |
+ if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1945 |
+ ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1946 |
+ SWITicks = (19 + memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1947 |
+ } |
|
| 1948 |
+ BIOS_LZ77UnCompVram(); |
|
| 1949 |
+ break; |
|
| 1950 |
+ case 0x13: |
|
| 1951 |
+ {
|
|
| 1952 |
+ u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1953 |
+ if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1954 |
+ ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1955 |
+ SWITicks = (29 + (memoryWait[(reg[0].I>>24) & 0xF]<<1)) * len; |
|
| 1956 |
+ } |
|
| 1957 |
+ BIOS_HuffUnComp(); |
|
| 1958 |
+ break; |
|
| 1959 |
+ case 0x14: |
|
| 1960 |
+ {
|
|
| 1961 |
+ u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1962 |
+ if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1963 |
+ ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1964 |
+ SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] + |
|
| 1965 |
+ memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1966 |
+ } |
|
| 1967 |
+ BIOS_RLUnCompWram(); |
|
| 1968 |
+ break; |
|
| 1969 |
+ case 0x15: |
|
| 1970 |
+ {
|
|
| 1971 |
+ u32 len = CPUReadMemory(reg[0].I) >> 9; |
|
| 1972 |
+ if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1973 |
+ ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1974 |
+ SWITicks = (34 + (memoryWait[(reg[0].I>>24) & 0xF] << 1) + |
|
| 1975 |
+ memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1976 |
+ } |
|
| 1977 |
+ BIOS_RLUnCompVram(); |
|
| 1978 |
+ break; |
|
| 1979 |
+ case 0x16: |
|
| 1980 |
+ {
|
|
| 1981 |
+ u32 len = CPUReadMemory(reg[0].I) >> 8; |
|
| 1982 |
+ if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1983 |
+ ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1984 |
+ SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] + |
|
| 1985 |
+ memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1986 |
+ } |
|
| 1987 |
+ BIOS_Diff8bitUnFilterWram(); |
|
| 1988 |
+ break; |
|
| 1989 |
+ case 0x17: |
|
| 1990 |
+ {
|
|
| 1991 |
+ u32 len = CPUReadMemory(reg[0].I) >> 9; |
|
| 1992 |
+ if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 1993 |
+ ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 1994 |
+ SWITicks = (39 + (memoryWait[(reg[0].I>>24) & 0xF]<<1) + |
|
| 1995 |
+ memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 1996 |
+ } |
|
| 1997 |
+ BIOS_Diff8bitUnFilterVram(); |
|
| 1998 |
+ break; |
|
| 1999 |
+ case 0x18: |
|
| 2000 |
+ {
|
|
| 2001 |
+ u32 len = CPUReadMemory(reg[0].I) >> 9; |
|
| 2002 |
+ if(!(((reg[0].I & 0xe000000) == 0) || |
|
| 2003 |
+ ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) |
|
| 2004 |
+ SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] + |
|
| 2005 |
+ memoryWait[(reg[1].I>>24) & 0xF]) * len; |
|
| 2006 |
+ } |
|
| 2007 |
+ BIOS_Diff16bitUnFilter(); |
|
| 2008 |
+ break; |
|
| 2009 |
+ case 0x19: |
|
| 2010 |
+#ifdef GBA_LOGGING |
|
| 2011 |
+ if(systemVerbose & VERBOSE_SWI) {
|
|
| 2012 |
+ log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n",
|
|
| 2013 |
+ reg[0].I, |
|
| 2014 |
+ VCOUNT); |
|
| 2015 |
+ } |
|
| 2016 |
+#endif |
|
| 2017 |
+ if(reg[0].I) |
|
| 2018 |
+ soundPause(); |
|
| 2019 |
+ else |
|
| 2020 |
+ soundResume(); |
|
| 2021 |
+ break; |
|
| 2022 |
+ case 0x1F: |
|
| 2023 |
+ BIOS_MidiKey2Freq(); |
|
| 2024 |
+ break; |
|
| 2025 |
+ case 0x2A: |
|
| 2026 |
+ BIOS_SndDriverJmpTableCopy(); |
|
| 2027 |
+ // let it go, because we don't really emulate this function |
|
| 2028 |
+ default: |
|
| 2029 |
+#ifdef GBA_LOGGING |
|
| 2030 |
+ if(systemVerbose & VERBOSE_SWI) {
|
|
| 2031 |
+ log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
|
| 2032 |
+ armState ? armNextPC - 4: armNextPC -2, |
|
| 2033 |
+ reg[0].I, |
|
| 2034 |
+ reg[1].I, |
|
| 2035 |
+ reg[2].I, |
|
| 2036 |
+ VCOUNT); |
|
| 2037 |
+ } |
|
| 2038 |
+#endif |
|
| 2039 |
+ |
|
| 2040 |
+ if(!disableMessage) {
|
|
| 2041 |
+ /*systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION, |
|
| 2042 |
+ N_("Unsupported BIOS function %02x called from %08x. A BIOS file is needed in order to get correct behaviour."),
|
|
| 2043 |
+ comment, |
|
| 2044 |
+ armMode ? armNextPC - 4: armNextPC - 2);*/ |
|
| 2045 |
+ disableMessage = true; |
|
| 2046 |
+ } |
|
| 2047 |
+ break; |
|
| 2048 |
+ } |
|
| 2049 |
+} |
|
| 2050 |
+ |
|
| 2051 |
+void CPUCompareVCOUNT() |
|
| 2052 |
+{
|
|
| 2053 |
+ if(VCOUNT == (DISPSTAT >> 8)) {
|
|
| 2054 |
+ DISPSTAT |= 4; |
|
| 2055 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 2056 |
+ |
|
| 2057 |
+ if(DISPSTAT & 0x20) {
|
|
| 2058 |
+ IF |= 4; |
|
| 2059 |
+ UPDATE_REG(0x202, IF); |
|
| 2060 |
+ } |
|
| 2061 |
+ } else {
|
|
| 2062 |
+ DISPSTAT &= 0xFFFB; |
|
| 2063 |
+ UPDATE_REG(0x4, DISPSTAT); |
|
| 2064 |
+ } |
|
| 2065 |
+ if (layerEnableDelay>0) |
|
| 2066 |
+ {
|
|
| 2067 |
+ layerEnableDelay--; |
|
| 2068 |
+ if (layerEnableDelay==1) |
|
| 2069 |
+ layerEnable = layerSettings & DISPCNT; |
|
| 2070 |
+ } |
|
| 2071 |
+ |
|
| 2072 |
+} |
|
| 2073 |
+ |
|
| 2074 |
+void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32) |
|
| 2075 |
+{
|
|
| 2076 |
+ int sm = s >> 24; |
|
| 2077 |
+ int dm = d >> 24; |
|
| 2078 |
+ int sw = 0; |
|
| 2079 |
+ int dw = 0; |
|
| 2080 |
+ int sc = c; |
|
| 2081 |
+ |
|
| 2082 |
+ cpuDmaCount = c; |
|
| 2083 |
+ // This is done to get the correct waitstates. |
|
| 2084 |
+ if (sm>15) |
|
| 2085 |
+ sm=15; |
|
| 2086 |
+ if (dm>15) |
|
| 2087 |
+ dm=15; |
|
| 2088 |
+ |
|
| 2089 |
+ //if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07)) |
|
| 2090 |
+ // blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ? true : false); |
|
| 2091 |
+ |
|
| 2092 |
+ if(transfer32) {
|
|
| 2093 |
+ s &= 0xFFFFFFFC; |
|
| 2094 |
+ if(s < 0x02000000 && (reg[15].I >> 24)) {
|
|
| 2095 |
+ while(c != 0) {
|
|
| 2096 |
+ CPUWriteMemory(d, 0); |
|
| 2097 |
+ d += di; |
|
| 2098 |
+ c--; |
|
| 2099 |
+ } |
|
| 2100 |
+ } else {
|
|
| 2101 |
+ while(c != 0) {
|
|
| 2102 |
+ cpuDmaLast = CPUReadMemory(s); |
|
| 2103 |
+ CPUWriteMemory(d, cpuDmaLast); |
|
| 2104 |
+ d += di; |
|
| 2105 |
+ s += si; |
|
| 2106 |
+ c--; |
|
| 2107 |
+ } |
|
| 2108 |
+ } |
|
| 2109 |
+ } else {
|
|
| 2110 |
+ s &= 0xFFFFFFFE; |
|
| 2111 |
+ si = (int)si >> 1; |
|
| 2112 |
+ di = (int)di >> 1; |
|
| 2113 |
+ if(s < 0x02000000 && (reg[15].I >> 24)) {
|
|
| 2114 |
+ while(c != 0) {
|
|
| 2115 |
+ CPUWriteHalfWord(d, 0); |
|
| 2116 |
+ d += di; |
|
| 2117 |
+ c--; |
|
| 2118 |
+ } |
|
| 2119 |
+ } else {
|
|
| 2120 |
+ while(c != 0) {
|
|
| 2121 |
+ cpuDmaLast = CPUReadHalfWord(s); |
|
| 2122 |
+ CPUWriteHalfWord(d, cpuDmaLast); |
|
| 2123 |
+ cpuDmaLast |= (cpuDmaLast<<16); |
|
| 2124 |
+ d += di; |
|
| 2125 |
+ s += si; |
|
| 2126 |
+ c--; |
|
| 2127 |
+ } |
|
| 2128 |
+ } |
|
| 2129 |
+ } |
|
| 2130 |
+ |
|
| 2131 |
+ cpuDmaCount = 0; |
|
| 2132 |
+ |
|
| 2133 |
+ int totalTicks = 0; |
|
| 2134 |
+ |
|
| 2135 |
+ if(transfer32) {
|
|
| 2136 |
+ sw =1+memoryWaitSeq32[sm & 15]; |
|
| 2137 |
+ dw =1+memoryWaitSeq32[dm & 15]; |
|
| 2138 |
+ totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait32[sm & 15] + |
|
| 2139 |
+ memoryWaitSeq32[dm & 15]; |
|
| 2140 |
+ } |
|
| 2141 |
+ else |
|
| 2142 |
+ {
|
|
| 2143 |
+ sw = 1+memoryWaitSeq[sm & 15]; |
|
| 2144 |
+ dw = 1+memoryWaitSeq[dm & 15]; |
|
| 2145 |
+ totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait[sm & 15] + |
|
| 2146 |
+ memoryWaitSeq[dm & 15]; |
|
| 2147 |
+ } |
|
| 2148 |
+ |
|
| 2149 |
+ cpuDmaTicksToUpdate += totalTicks; |
|
| 2150 |
+ |
|
| 2151 |
+} |
|
| 2152 |
+ |
|
| 2153 |
+void CPUCheckDMA(int reason, int dmamask) |
|
| 2154 |
+{
|
|
| 2155 |
+ // DMA 0 |
|
| 2156 |
+ if((DM0CNT_H & 0x8000) && (dmamask & 1)) {
|
|
| 2157 |
+ if(((DM0CNT_H >> 12) & 3) == reason) {
|
|
| 2158 |
+ u32 sourceIncrement = 4; |
|
| 2159 |
+ u32 destIncrement = 4; |
|
| 2160 |
+ switch((DM0CNT_H >> 7) & 3) {
|
|
| 2161 |
+ case 0: |
|
| 2162 |
+ break; |
|
| 2163 |
+ case 1: |
|
| 2164 |
+ sourceIncrement = (u32)-4; |
|
| 2165 |
+ break; |
|
| 2166 |
+ case 2: |
|
| 2167 |
+ sourceIncrement = 0; |
|
| 2168 |
+ break; |
|
| 2169 |
+ } |
|
| 2170 |
+ switch((DM0CNT_H >> 5) & 3) {
|
|
| 2171 |
+ case 0: |
|
| 2172 |
+ break; |
|
| 2173 |
+ case 1: |
|
| 2174 |
+ destIncrement = (u32)-4; |
|
| 2175 |
+ break; |
|
| 2176 |
+ case 2: |
|
| 2177 |
+ destIncrement = 0; |
|
| 2178 |
+ break; |
|
| 2179 |
+ } |
|
| 2180 |
+#ifdef GBA_LOGGING |
|
| 2181 |
+ if(systemVerbose & VERBOSE_DMA0) {
|
|
| 2182 |
+ int count = (DM0CNT_L ? DM0CNT_L : 0x4000) << 1; |
|
| 2183 |
+ if(DM0CNT_H & 0x0400) |
|
| 2184 |
+ count <<= 1; |
|
| 2185 |
+ log("DMA0: s=%08x d=%08x c=%04x count=%08x\n", dma0Source, dma0Dest,
|
|
| 2186 |
+ DM0CNT_H, |
|
| 2187 |
+ count); |
|
| 2188 |
+ } |
|
| 2189 |
+#endif |
|
| 2190 |
+ doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, |
|
| 2191 |
+ DM0CNT_L ? DM0CNT_L : 0x4000, |
|
| 2192 |
+ DM0CNT_H & 0x0400); |
|
| 2193 |
+ cpuDmaHack = true; |
|
| 2194 |
+ |
|
| 2195 |
+ if(DM0CNT_H & 0x4000) {
|
|
| 2196 |
+ IF |= 0x0100; |
|
| 2197 |
+ UPDATE_REG(0x202, IF); |
|
| 2198 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2199 |
+ } |
|
| 2200 |
+ |
|
| 2201 |
+ if(((DM0CNT_H >> 5) & 3) == 3) {
|
|
| 2202 |
+ dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 2203 |
+ } |
|
| 2204 |
+ |
|
| 2205 |
+ if(!(DM0CNT_H & 0x0200) || (reason == 0)) {
|
|
| 2206 |
+ DM0CNT_H &= 0x7FFF; |
|
| 2207 |
+ UPDATE_REG(0xBA, DM0CNT_H); |
|
| 2208 |
+ } |
|
| 2209 |
+ } |
|
| 2210 |
+ } |
|
| 2211 |
+ |
|
| 2212 |
+ // DMA 1 |
|
| 2213 |
+ if((DM1CNT_H & 0x8000) && (dmamask & 2)) {
|
|
| 2214 |
+ if(((DM1CNT_H >> 12) & 3) == reason) {
|
|
| 2215 |
+ u32 sourceIncrement = 4; |
|
| 2216 |
+ u32 destIncrement = 4; |
|
| 2217 |
+ switch((DM1CNT_H >> 7) & 3) {
|
|
| 2218 |
+ case 0: |
|
| 2219 |
+ break; |
|
| 2220 |
+ case 1: |
|
| 2221 |
+ sourceIncrement = (u32)-4; |
|
| 2222 |
+ break; |
|
| 2223 |
+ case 2: |
|
| 2224 |
+ sourceIncrement = 0; |
|
| 2225 |
+ break; |
|
| 2226 |
+ } |
|
| 2227 |
+ switch((DM1CNT_H >> 5) & 3) {
|
|
| 2228 |
+ case 0: |
|
| 2229 |
+ break; |
|
| 2230 |
+ case 1: |
|
| 2231 |
+ destIncrement = (u32)-4; |
|
| 2232 |
+ break; |
|
| 2233 |
+ case 2: |
|
| 2234 |
+ destIncrement = 0; |
|
| 2235 |
+ break; |
|
| 2236 |
+ } |
|
| 2237 |
+ if(reason == 3) {
|
|
| 2238 |
+#ifdef GBA_LOGGING |
|
| 2239 |
+ if(systemVerbose & VERBOSE_DMA1) {
|
|
| 2240 |
+ log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
|
|
| 2241 |
+ DM1CNT_H, |
|
| 2242 |
+ 16); |
|
| 2243 |
+ } |
|
| 2244 |
+#endif |
|
| 2245 |
+ doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, |
|
| 2246 |
+ 0x0400); |
|
| 2247 |
+ } else {
|
|
| 2248 |
+#ifdef GBA_LOGGING |
|
| 2249 |
+ if(systemVerbose & VERBOSE_DMA1) {
|
|
| 2250 |
+ int count = (DM1CNT_L ? DM1CNT_L : 0x4000) << 1; |
|
| 2251 |
+ if(DM1CNT_H & 0x0400) |
|
| 2252 |
+ count <<= 1; |
|
| 2253 |
+ log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
|
|
| 2254 |
+ DM1CNT_H, |
|
| 2255 |
+ count); |
|
| 2256 |
+ } |
|
| 2257 |
+#endif |
|
| 2258 |
+ doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, |
|
| 2259 |
+ DM1CNT_L ? DM1CNT_L : 0x4000, |
|
| 2260 |
+ DM1CNT_H & 0x0400); |
|
| 2261 |
+ } |
|
| 2262 |
+ cpuDmaHack = true; |
|
| 2263 |
+ |
|
| 2264 |
+ if(DM1CNT_H & 0x4000) {
|
|
| 2265 |
+ IF |= 0x0200; |
|
| 2266 |
+ UPDATE_REG(0x202, IF); |
|
| 2267 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2268 |
+ } |
|
| 2269 |
+ |
|
| 2270 |
+ if(((DM1CNT_H >> 5) & 3) == 3) {
|
|
| 2271 |
+ dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 2272 |
+ } |
|
| 2273 |
+ |
|
| 2274 |
+ if(!(DM1CNT_H & 0x0200) || (reason == 0)) {
|
|
| 2275 |
+ DM1CNT_H &= 0x7FFF; |
|
| 2276 |
+ UPDATE_REG(0xC6, DM1CNT_H); |
|
| 2277 |
+ } |
|
| 2278 |
+ } |
|
| 2279 |
+ } |
|
| 2280 |
+ |
|
| 2281 |
+ // DMA 2 |
|
| 2282 |
+ if((DM2CNT_H & 0x8000) && (dmamask & 4)) {
|
|
| 2283 |
+ if(((DM2CNT_H >> 12) & 3) == reason) {
|
|
| 2284 |
+ u32 sourceIncrement = 4; |
|
| 2285 |
+ u32 destIncrement = 4; |
|
| 2286 |
+ switch((DM2CNT_H >> 7) & 3) {
|
|
| 2287 |
+ case 0: |
|
| 2288 |
+ break; |
|
| 2289 |
+ case 1: |
|
| 2290 |
+ sourceIncrement = (u32)-4; |
|
| 2291 |
+ break; |
|
| 2292 |
+ case 2: |
|
| 2293 |
+ sourceIncrement = 0; |
|
| 2294 |
+ break; |
|
| 2295 |
+ } |
|
| 2296 |
+ switch((DM2CNT_H >> 5) & 3) {
|
|
| 2297 |
+ case 0: |
|
| 2298 |
+ break; |
|
| 2299 |
+ case 1: |
|
| 2300 |
+ destIncrement = (u32)-4; |
|
| 2301 |
+ break; |
|
| 2302 |
+ case 2: |
|
| 2303 |
+ destIncrement = 0; |
|
| 2304 |
+ break; |
|
| 2305 |
+ } |
|
| 2306 |
+ if(reason == 3) {
|
|
| 2307 |
+#ifdef GBA_LOGGING |
|
| 2308 |
+ if(systemVerbose & VERBOSE_DMA2) {
|
|
| 2309 |
+ int count = (4) << 2; |
|
| 2310 |
+ log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
|
|
| 2311 |
+ DM2CNT_H, |
|
| 2312 |
+ count); |
|
| 2313 |
+ } |
|
| 2314 |
+#endif |
|
| 2315 |
+ doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, |
|
| 2316 |
+ 0x0400); |
|
| 2317 |
+ } else {
|
|
| 2318 |
+#ifdef GBA_LOGGING |
|
| 2319 |
+ if(systemVerbose & VERBOSE_DMA2) {
|
|
| 2320 |
+ int count = (DM2CNT_L ? DM2CNT_L : 0x4000) << 1; |
|
| 2321 |
+ if(DM2CNT_H & 0x0400) |
|
| 2322 |
+ count <<= 1; |
|
| 2323 |
+ log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
|
|
| 2324 |
+ DM2CNT_H, |
|
| 2325 |
+ count); |
|
| 2326 |
+ } |
|
| 2327 |
+#endif |
|
| 2328 |
+ doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, |
|
| 2329 |
+ DM2CNT_L ? DM2CNT_L : 0x4000, |
|
| 2330 |
+ DM2CNT_H & 0x0400); |
|
| 2331 |
+ } |
|
| 2332 |
+ cpuDmaHack = true; |
|
| 2333 |
+ |
|
| 2334 |
+ if(DM2CNT_H & 0x4000) {
|
|
| 2335 |
+ IF |= 0x0400; |
|
| 2336 |
+ UPDATE_REG(0x202, IF); |
|
| 2337 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2338 |
+ } |
|
| 2339 |
+ |
|
| 2340 |
+ if(((DM2CNT_H >> 5) & 3) == 3) {
|
|
| 2341 |
+ dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 2342 |
+ } |
|
| 2343 |
+ |
|
| 2344 |
+ if(!(DM2CNT_H & 0x0200) || (reason == 0)) {
|
|
| 2345 |
+ DM2CNT_H &= 0x7FFF; |
|
| 2346 |
+ UPDATE_REG(0xD2, DM2CNT_H); |
|
| 2347 |
+ } |
|
| 2348 |
+ } |
|
| 2349 |
+ } |
|
| 2350 |
+ |
|
| 2351 |
+ // DMA 3 |
|
| 2352 |
+ if((DM3CNT_H & 0x8000) && (dmamask & 8)) {
|
|
| 2353 |
+ if(((DM3CNT_H >> 12) & 3) == reason) {
|
|
| 2354 |
+ u32 sourceIncrement = 4; |
|
| 2355 |
+ u32 destIncrement = 4; |
|
| 2356 |
+ switch((DM3CNT_H >> 7) & 3) {
|
|
| 2357 |
+ case 0: |
|
| 2358 |
+ break; |
|
| 2359 |
+ case 1: |
|
| 2360 |
+ sourceIncrement = (u32)-4; |
|
| 2361 |
+ break; |
|
| 2362 |
+ case 2: |
|
| 2363 |
+ sourceIncrement = 0; |
|
| 2364 |
+ break; |
|
| 2365 |
+ } |
|
| 2366 |
+ switch((DM3CNT_H >> 5) & 3) {
|
|
| 2367 |
+ case 0: |
|
| 2368 |
+ break; |
|
| 2369 |
+ case 1: |
|
| 2370 |
+ destIncrement = (u32)-4; |
|
| 2371 |
+ break; |
|
| 2372 |
+ case 2: |
|
| 2373 |
+ destIncrement = 0; |
|
| 2374 |
+ break; |
|
| 2375 |
+ } |
|
| 2376 |
+#ifdef GBA_LOGGING |
|
| 2377 |
+ if(systemVerbose & VERBOSE_DMA3) {
|
|
| 2378 |
+ int count = (DM3CNT_L ? DM3CNT_L : 0x10000) << 1; |
|
| 2379 |
+ if(DM3CNT_H & 0x0400) |
|
| 2380 |
+ count <<= 1; |
|
| 2381 |
+ log("DMA3: s=%08x d=%08x c=%04x count=%08x\n", dma3Source, dma3Dest,
|
|
| 2382 |
+ DM3CNT_H, |
|
| 2383 |
+ count); |
|
| 2384 |
+ } |
|
| 2385 |
+#endif |
|
| 2386 |
+ doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, |
|
| 2387 |
+ DM3CNT_L ? DM3CNT_L : 0x10000, |
|
| 2388 |
+ DM3CNT_H & 0x0400); |
|
| 2389 |
+ if(DM3CNT_H & 0x4000) {
|
|
| 2390 |
+ IF |= 0x0800; |
|
| 2391 |
+ UPDATE_REG(0x202, IF); |
|
| 2392 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2393 |
+ } |
|
| 2394 |
+ |
|
| 2395 |
+ if(((DM3CNT_H >> 5) & 3) == 3) {
|
|
| 2396 |
+ dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 2397 |
+ } |
|
| 2398 |
+ |
|
| 2399 |
+ if(!(DM3CNT_H & 0x0200) || (reason == 0)) {
|
|
| 2400 |
+ DM3CNT_H &= 0x7FFF; |
|
| 2401 |
+ UPDATE_REG(0xDE, DM3CNT_H); |
|
| 2402 |
+ } |
|
| 2403 |
+ } |
|
| 2404 |
+ } |
|
| 2405 |
+} |
|
| 2406 |
+ |
|
| 2407 |
+void CPUUpdateRegister(u32 address, u16 value) |
|
| 2408 |
+{
|
|
| 2409 |
+ switch(address) |
|
| 2410 |
+ {
|
|
| 2411 |
+ case 0x00: |
|
| 2412 |
+ { // we need to place the following code in { } because we declare & initialize variables in a case statement
|
|
| 2413 |
+ if((value & 7) > 5) {
|
|
| 2414 |
+ // display modes above 0-5 are prohibited |
|
| 2415 |
+ DISPCNT = (value & 7); |
|
| 2416 |
+ } |
|
| 2417 |
+ bool change = (0 != ((DISPCNT ^ value) & 0x80)); |
|
| 2418 |
+ bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00)); |
|
| 2419 |
+ u16 changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated |
|
| 2420 |
+ |
|
| 2421 |
+ DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode |
|
| 2422 |
+ UPDATE_REG(0x00, DISPCNT); |
|
| 2423 |
+ |
|
| 2424 |
+ if(changeBGon) {
|
|
| 2425 |
+ layerEnableDelay = 4; |
|
| 2426 |
+ layerEnable = layerSettings & value & (~changeBGon); |
|
| 2427 |
+ } else {
|
|
| 2428 |
+ layerEnable = layerSettings & value; |
|
| 2429 |
+ // CPUUpdateTicks(); |
|
| 2430 |
+ } |
|
| 2431 |
+ |
|
| 2432 |
+ windowOn = (layerEnable & 0x6000) ? true : false; |
|
| 2433 |
+ if(change && !((value & 0x80))) {
|
|
| 2434 |
+ if(!(DISPSTAT & 1)) {
|
|
| 2435 |
+ lcdTicks = 1008; |
|
| 2436 |
+ // VCOUNT = 0; |
|
| 2437 |
+ // UPDATE_REG(0x06, VCOUNT); |
|
| 2438 |
+ DISPSTAT &= 0xFFFC; |
|
| 2439 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 2440 |
+ CPUCompareVCOUNT(); |
|
| 2441 |
+ } |
|
| 2442 |
+ // (*renderLine)(); |
|
| 2443 |
+ } |
|
| 2444 |
+ //CPUUpdateRender(); |
|
| 2445 |
+ // we only care about changes in BG0-BG3 |
|
| 2446 |
+ if(changeBG) {
|
|
| 2447 |
+ //CPUUpdateRenderBuffers(false); |
|
| 2448 |
+ } |
|
| 2449 |
+ break; |
|
| 2450 |
+ } |
|
| 2451 |
+ case 0x04: |
|
| 2452 |
+ DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7); |
|
| 2453 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 2454 |
+ break; |
|
| 2455 |
+ case 0x06: |
|
| 2456 |
+ // not writable |
|
| 2457 |
+ break; |
|
| 2458 |
+ case 0x08: |
|
| 2459 |
+ BG0CNT = (value & 0xDFCF); |
|
| 2460 |
+ UPDATE_REG(0x08, BG0CNT); |
|
| 2461 |
+ break; |
|
| 2462 |
+ case 0x0A: |
|
| 2463 |
+ BG1CNT = (value & 0xDFCF); |
|
| 2464 |
+ UPDATE_REG(0x0A, BG1CNT); |
|
| 2465 |
+ break; |
|
| 2466 |
+ case 0x0C: |
|
| 2467 |
+ BG2CNT = (value & 0xFFCF); |
|
| 2468 |
+ UPDATE_REG(0x0C, BG2CNT); |
|
| 2469 |
+ break; |
|
| 2470 |
+ case 0x0E: |
|
| 2471 |
+ BG3CNT = (value & 0xFFCF); |
|
| 2472 |
+ UPDATE_REG(0x0E, BG3CNT); |
|
| 2473 |
+ break; |
|
| 2474 |
+ case 0x10: |
|
| 2475 |
+ BG0HOFS = value & 511; |
|
| 2476 |
+ UPDATE_REG(0x10, BG0HOFS); |
|
| 2477 |
+ break; |
|
| 2478 |
+ case 0x12: |
|
| 2479 |
+ BG0VOFS = value & 511; |
|
| 2480 |
+ UPDATE_REG(0x12, BG0VOFS); |
|
| 2481 |
+ break; |
|
| 2482 |
+ case 0x14: |
|
| 2483 |
+ BG1HOFS = value & 511; |
|
| 2484 |
+ UPDATE_REG(0x14, BG1HOFS); |
|
| 2485 |
+ break; |
|
| 2486 |
+ case 0x16: |
|
| 2487 |
+ BG1VOFS = value & 511; |
|
| 2488 |
+ UPDATE_REG(0x16, BG1VOFS); |
|
| 2489 |
+ break; |
|
| 2490 |
+ case 0x18: |
|
| 2491 |
+ BG2HOFS = value & 511; |
|
| 2492 |
+ UPDATE_REG(0x18, BG2HOFS); |
|
| 2493 |
+ break; |
|
| 2494 |
+ case 0x1A: |
|
| 2495 |
+ BG2VOFS = value & 511; |
|
| 2496 |
+ UPDATE_REG(0x1A, BG2VOFS); |
|
| 2497 |
+ break; |
|
| 2498 |
+ case 0x1C: |
|
| 2499 |
+ BG3HOFS = value & 511; |
|
| 2500 |
+ UPDATE_REG(0x1C, BG3HOFS); |
|
| 2501 |
+ break; |
|
| 2502 |
+ case 0x1E: |
|
| 2503 |
+ BG3VOFS = value & 511; |
|
| 2504 |
+ UPDATE_REG(0x1E, BG3VOFS); |
|
| 2505 |
+ break; |
|
| 2506 |
+ case 0x20: |
|
| 2507 |
+ BG2PA = value; |
|
| 2508 |
+ UPDATE_REG(0x20, BG2PA); |
|
| 2509 |
+ break; |
|
| 2510 |
+ case 0x22: |
|
| 2511 |
+ BG2PB = value; |
|
| 2512 |
+ UPDATE_REG(0x22, BG2PB); |
|
| 2513 |
+ break; |
|
| 2514 |
+ case 0x24: |
|
| 2515 |
+ BG2PC = value; |
|
| 2516 |
+ UPDATE_REG(0x24, BG2PC); |
|
| 2517 |
+ break; |
|
| 2518 |
+ case 0x26: |
|
| 2519 |
+ BG2PD = value; |
|
| 2520 |
+ UPDATE_REG(0x26, BG2PD); |
|
| 2521 |
+ break; |
|
| 2522 |
+ case 0x28: |
|
| 2523 |
+ BG2X_L = value; |
|
| 2524 |
+ UPDATE_REG(0x28, BG2X_L); |
|
| 2525 |
+ //gfxBG2Changed |= 1; |
|
| 2526 |
+ break; |
|
| 2527 |
+ case 0x2A: |
|
| 2528 |
+ BG2X_H = (value & 0xFFF); |
|
| 2529 |
+ UPDATE_REG(0x2A, BG2X_H); |
|
| 2530 |
+ //gfxBG2Changed |= 1; |
|
| 2531 |
+ break; |
|
| 2532 |
+ case 0x2C: |
|
| 2533 |
+ BG2Y_L = value; |
|
| 2534 |
+ UPDATE_REG(0x2C, BG2Y_L); |
|
| 2535 |
+ //gfxBG2Changed |= 2; |
|
| 2536 |
+ break; |
|
| 2537 |
+ case 0x2E: |
|
| 2538 |
+ BG2Y_H = value & 0xFFF; |
|
| 2539 |
+ UPDATE_REG(0x2E, BG2Y_H); |
|
| 2540 |
+ //gfxBG2Changed |= 2; |
|
| 2541 |
+ break; |
|
| 2542 |
+ case 0x30: |
|
| 2543 |
+ BG3PA = value; |
|
| 2544 |
+ UPDATE_REG(0x30, BG3PA); |
|
| 2545 |
+ break; |
|
| 2546 |
+ case 0x32: |
|
| 2547 |
+ BG3PB = value; |
|
| 2548 |
+ UPDATE_REG(0x32, BG3PB); |
|
| 2549 |
+ break; |
|
| 2550 |
+ case 0x34: |
|
| 2551 |
+ BG3PC = value; |
|
| 2552 |
+ UPDATE_REG(0x34, BG3PC); |
|
| 2553 |
+ break; |
|
| 2554 |
+ case 0x36: |
|
| 2555 |
+ BG3PD = value; |
|
| 2556 |
+ UPDATE_REG(0x36, BG3PD); |
|
| 2557 |
+ break; |
|
| 2558 |
+ case 0x38: |
|
| 2559 |
+ BG3X_L = value; |
|
| 2560 |
+ UPDATE_REG(0x38, BG3X_L); |
|
| 2561 |
+ //gfxBG3Changed |= 1; |
|
| 2562 |
+ break; |
|
| 2563 |
+ case 0x3A: |
|
| 2564 |
+ BG3X_H = value & 0xFFF; |
|
| 2565 |
+ UPDATE_REG(0x3A, BG3X_H); |
|
| 2566 |
+ //gfxBG3Changed |= 1; |
|
| 2567 |
+ break; |
|
| 2568 |
+ case 0x3C: |
|
| 2569 |
+ BG3Y_L = value; |
|
| 2570 |
+ UPDATE_REG(0x3C, BG3Y_L); |
|
| 2571 |
+ //gfxBG3Changed |= 2; |
|
| 2572 |
+ break; |
|
| 2573 |
+ case 0x3E: |
|
| 2574 |
+ BG3Y_H = value & 0xFFF; |
|
| 2575 |
+ UPDATE_REG(0x3E, BG3Y_H); |
|
| 2576 |
+ //gfxBG3Changed |= 2; |
|
| 2577 |
+ break; |
|
| 2578 |
+ case 0x40: |
|
| 2579 |
+ WIN0H = value; |
|
| 2580 |
+ UPDATE_REG(0x40, WIN0H); |
|
| 2581 |
+ //CPUUpdateWindow0(); |
|
| 2582 |
+ break; |
|
| 2583 |
+ case 0x42: |
|
| 2584 |
+ WIN1H = value; |
|
| 2585 |
+ UPDATE_REG(0x42, WIN1H); |
|
| 2586 |
+ //CPUUpdateWindow1(); |
|
| 2587 |
+ break; |
|
| 2588 |
+ case 0x44: |
|
| 2589 |
+ WIN0V = value; |
|
| 2590 |
+ UPDATE_REG(0x44, WIN0V); |
|
| 2591 |
+ break; |
|
| 2592 |
+ case 0x46: |
|
| 2593 |
+ WIN1V = value; |
|
| 2594 |
+ UPDATE_REG(0x46, WIN1V); |
|
| 2595 |
+ break; |
|
| 2596 |
+ case 0x48: |
|
| 2597 |
+ WININ = value & 0x3F3F; |
|
| 2598 |
+ UPDATE_REG(0x48, WININ); |
|
| 2599 |
+ break; |
|
| 2600 |
+ case 0x4A: |
|
| 2601 |
+ WINOUT = value & 0x3F3F; |
|
| 2602 |
+ UPDATE_REG(0x4A, WINOUT); |
|
| 2603 |
+ break; |
|
| 2604 |
+ case 0x4C: |
|
| 2605 |
+ MOSAIC = value; |
|
| 2606 |
+ UPDATE_REG(0x4C, MOSAIC); |
|
| 2607 |
+ break; |
|
| 2608 |
+ case 0x50: |
|
| 2609 |
+ BLDMOD = value & 0x3FFF; |
|
| 2610 |
+ UPDATE_REG(0x50, BLDMOD); |
|
| 2611 |
+ fxOn = ((BLDMOD>>6)&3) != 0; |
|
| 2612 |
+ //CPUUpdateRender(); |
|
| 2613 |
+ break; |
|
| 2614 |
+ case 0x52: |
|
| 2615 |
+ COLEV = value & 0x1F1F; |
|
| 2616 |
+ UPDATE_REG(0x52, COLEV); |
|
| 2617 |
+ break; |
|
| 2618 |
+ case 0x54: |
|
| 2619 |
+ COLY = value & 0x1F; |
|
| 2620 |
+ UPDATE_REG(0x54, COLY); |
|
| 2621 |
+ break; |
|
| 2622 |
+ case 0x60: |
|
| 2623 |
+ case 0x62: |
|
| 2624 |
+ case 0x64: |
|
| 2625 |
+ case 0x68: |
|
| 2626 |
+ case 0x6c: |
|
| 2627 |
+ case 0x70: |
|
| 2628 |
+ case 0x72: |
|
| 2629 |
+ case 0x74: |
|
| 2630 |
+ case 0x78: |
|
| 2631 |
+ case 0x7c: |
|
| 2632 |
+ case 0x80: |
|
| 2633 |
+ case 0x84: |
|
| 2634 |
+ soundEvent(address&0xFF, (u8)(value & 0xFF)); |
|
| 2635 |
+ soundEvent((address&0xFF)+1, (u8)(value>>8)); |
|
| 2636 |
+ break; |
|
| 2637 |
+ case 0x82: |
|
| 2638 |
+ case 0x88: |
|
| 2639 |
+ case 0xa0: |
|
| 2640 |
+ case 0xa2: |
|
| 2641 |
+ case 0xa4: |
|
| 2642 |
+ case 0xa6: |
|
| 2643 |
+ case 0x90: |
|
| 2644 |
+ case 0x92: |
|
| 2645 |
+ case 0x94: |
|
| 2646 |
+ case 0x96: |
|
| 2647 |
+ case 0x98: |
|
| 2648 |
+ case 0x9a: |
|
| 2649 |
+ case 0x9c: |
|
| 2650 |
+ case 0x9e: |
|
| 2651 |
+ soundEvent(address&0xFF, value); |
|
| 2652 |
+ break; |
|
| 2653 |
+ case 0xB0: |
|
| 2654 |
+ DM0SAD_L = value; |
|
| 2655 |
+ UPDATE_REG(0xB0, DM0SAD_L); |
|
| 2656 |
+ break; |
|
| 2657 |
+ case 0xB2: |
|
| 2658 |
+ DM0SAD_H = value & 0x07FF; |
|
| 2659 |
+ UPDATE_REG(0xB2, DM0SAD_H); |
|
| 2660 |
+ break; |
|
| 2661 |
+ case 0xB4: |
|
| 2662 |
+ DM0DAD_L = value; |
|
| 2663 |
+ UPDATE_REG(0xB4, DM0DAD_L); |
|
| 2664 |
+ break; |
|
| 2665 |
+ case 0xB6: |
|
| 2666 |
+ DM0DAD_H = value & 0x07FF; |
|
| 2667 |
+ UPDATE_REG(0xB6, DM0DAD_H); |
|
| 2668 |
+ break; |
|
| 2669 |
+ case 0xB8: |
|
| 2670 |
+ DM0CNT_L = value & 0x3FFF; |
|
| 2671 |
+ UPDATE_REG(0xB8, 0); |
|
| 2672 |
+ break; |
|
| 2673 |
+ case 0xBA: |
|
| 2674 |
+ {
|
|
| 2675 |
+ bool start = ((DM0CNT_H ^ value) & 0x8000) ? true : false; |
|
| 2676 |
+ value &= 0xF7E0; |
|
| 2677 |
+ |
|
| 2678 |
+ DM0CNT_H = value; |
|
| 2679 |
+ UPDATE_REG(0xBA, DM0CNT_H); |
|
| 2680 |
+ |
|
| 2681 |
+ if(start && (value & 0x8000)) {
|
|
| 2682 |
+ dma0Source = DM0SAD_L | (DM0SAD_H << 16); |
|
| 2683 |
+ dma0Dest = DM0DAD_L | (DM0DAD_H << 16); |
|
| 2684 |
+ CPUCheckDMA(0, 1); |
|
| 2685 |
+ } |
|
| 2686 |
+ } |
|
| 2687 |
+ break; |
|
| 2688 |
+ case 0xBC: |
|
| 2689 |
+ DM1SAD_L = value; |
|
| 2690 |
+ UPDATE_REG(0xBC, DM1SAD_L); |
|
| 2691 |
+ break; |
|
| 2692 |
+ case 0xBE: |
|
| 2693 |
+ DM1SAD_H = value & 0x0FFF; |
|
| 2694 |
+ UPDATE_REG(0xBE, DM1SAD_H); |
|
| 2695 |
+ break; |
|
| 2696 |
+ case 0xC0: |
|
| 2697 |
+ DM1DAD_L = value; |
|
| 2698 |
+ UPDATE_REG(0xC0, DM1DAD_L); |
|
| 2699 |
+ break; |
|
| 2700 |
+ case 0xC2: |
|
| 2701 |
+ DM1DAD_H = value & 0x07FF; |
|
| 2702 |
+ UPDATE_REG(0xC2, DM1DAD_H); |
|
| 2703 |
+ break; |
|
| 2704 |
+ case 0xC4: |
|
| 2705 |
+ DM1CNT_L = value & 0x3FFF; |
|
| 2706 |
+ UPDATE_REG(0xC4, 0); |
|
| 2707 |
+ break; |
|
| 2708 |
+ case 0xC6: |
|
| 2709 |
+ {
|
|
| 2710 |
+ bool start = ((DM1CNT_H ^ value) & 0x8000) ? true : false; |
|
| 2711 |
+ value &= 0xF7E0; |
|
| 2712 |
+ |
|
| 2713 |
+ DM1CNT_H = value; |
|
| 2714 |
+ UPDATE_REG(0xC6, DM1CNT_H); |
|
| 2715 |
+ |
|
| 2716 |
+ if(start && (value & 0x8000)) {
|
|
| 2717 |
+ dma1Source = DM1SAD_L | (DM1SAD_H << 16); |
|
| 2718 |
+ dma1Dest = DM1DAD_L | (DM1DAD_H << 16); |
|
| 2719 |
+ CPUCheckDMA(0, 2); |
|
| 2720 |
+ } |
|
| 2721 |
+ } |
|
| 2722 |
+ break; |
|
| 2723 |
+ case 0xC8: |
|
| 2724 |
+ DM2SAD_L = value; |
|
| 2725 |
+ UPDATE_REG(0xC8, DM2SAD_L); |
|
| 2726 |
+ break; |
|
| 2727 |
+ case 0xCA: |
|
| 2728 |
+ DM2SAD_H = value & 0x0FFF; |
|
| 2729 |
+ UPDATE_REG(0xCA, DM2SAD_H); |
|
| 2730 |
+ break; |
|
| 2731 |
+ case 0xCC: |
|
| 2732 |
+ DM2DAD_L = value; |
|
| 2733 |
+ UPDATE_REG(0xCC, DM2DAD_L); |
|
| 2734 |
+ break; |
|
| 2735 |
+ case 0xCE: |
|
| 2736 |
+ DM2DAD_H = value & 0x07FF; |
|
| 2737 |
+ UPDATE_REG(0xCE, DM2DAD_H); |
|
| 2738 |
+ break; |
|
| 2739 |
+ case 0xD0: |
|
| 2740 |
+ DM2CNT_L = value & 0x3FFF; |
|
| 2741 |
+ UPDATE_REG(0xD0, 0); |
|
| 2742 |
+ break; |
|
| 2743 |
+ case 0xD2: |
|
| 2744 |
+ {
|
|
| 2745 |
+ bool start = ((DM2CNT_H ^ value) & 0x8000) ? true : false; |
|
| 2746 |
+ |
|
| 2747 |
+ value &= 0xF7E0; |
|
| 2748 |
+ |
|
| 2749 |
+ DM2CNT_H = value; |
|
| 2750 |
+ UPDATE_REG(0xD2, DM2CNT_H); |
|
| 2751 |
+ |
|
| 2752 |
+ if(start && (value & 0x8000)) {
|
|
| 2753 |
+ dma2Source = DM2SAD_L | (DM2SAD_H << 16); |
|
| 2754 |
+ dma2Dest = DM2DAD_L | (DM2DAD_H << 16); |
|
| 2755 |
+ |
|
| 2756 |
+ CPUCheckDMA(0, 4); |
|
| 2757 |
+ } |
|
| 2758 |
+ } |
|
| 2759 |
+ break; |
|
| 2760 |
+ case 0xD4: |
|
| 2761 |
+ DM3SAD_L = value; |
|
| 2762 |
+ UPDATE_REG(0xD4, DM3SAD_L); |
|
| 2763 |
+ break; |
|
| 2764 |
+ case 0xD6: |
|
| 2765 |
+ DM3SAD_H = value & 0x0FFF; |
|
| 2766 |
+ UPDATE_REG(0xD6, DM3SAD_H); |
|
| 2767 |
+ break; |
|
| 2768 |
+ case 0xD8: |
|
| 2769 |
+ DM3DAD_L = value; |
|
| 2770 |
+ UPDATE_REG(0xD8, DM3DAD_L); |
|
| 2771 |
+ break; |
|
| 2772 |
+ case 0xDA: |
|
| 2773 |
+ DM3DAD_H = value & 0x0FFF; |
|
| 2774 |
+ UPDATE_REG(0xDA, DM3DAD_H); |
|
| 2775 |
+ break; |
|
| 2776 |
+ case 0xDC: |
|
| 2777 |
+ DM3CNT_L = value; |
|
| 2778 |
+ UPDATE_REG(0xDC, 0); |
|
| 2779 |
+ break; |
|
| 2780 |
+ case 0xDE: |
|
| 2781 |
+ {
|
|
| 2782 |
+ bool start = ((DM3CNT_H ^ value) & 0x8000) ? true : false; |
|
| 2783 |
+ |
|
| 2784 |
+ value &= 0xFFE0; |
|
| 2785 |
+ |
|
| 2786 |
+ DM3CNT_H = value; |
|
| 2787 |
+ UPDATE_REG(0xDE, DM3CNT_H); |
|
| 2788 |
+ |
|
| 2789 |
+ if(start && (value & 0x8000)) {
|
|
| 2790 |
+ dma3Source = DM3SAD_L | (DM3SAD_H << 16); |
|
| 2791 |
+ dma3Dest = DM3DAD_L | (DM3DAD_H << 16); |
|
| 2792 |
+ CPUCheckDMA(0,8); |
|
| 2793 |
+ } |
|
| 2794 |
+ } |
|
| 2795 |
+ break; |
|
| 2796 |
+ case 0x100: |
|
| 2797 |
+ timer0Reload = value; |
|
| 2798 |
+ interp_rate(); |
|
| 2799 |
+ break; |
|
| 2800 |
+ case 0x102: |
|
| 2801 |
+ timer0Value = value; |
|
| 2802 |
+ timerOnOffDelay|=1; |
|
| 2803 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2804 |
+ break; |
|
| 2805 |
+ case 0x104: |
|
| 2806 |
+ timer1Reload = value; |
|
| 2807 |
+ interp_rate(); |
|
| 2808 |
+ break; |
|
| 2809 |
+ case 0x106: |
|
| 2810 |
+ timer1Value = value; |
|
| 2811 |
+ timerOnOffDelay|=2; |
|
| 2812 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2813 |
+ break; |
|
| 2814 |
+ case 0x108: |
|
| 2815 |
+ timer2Reload = value; |
|
| 2816 |
+ break; |
|
| 2817 |
+ case 0x10A: |
|
| 2818 |
+ timer2Value = value; |
|
| 2819 |
+ timerOnOffDelay|=4; |
|
| 2820 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2821 |
+ break; |
|
| 2822 |
+ case 0x10C: |
|
| 2823 |
+ timer3Reload = value; |
|
| 2824 |
+ break; |
|
| 2825 |
+ case 0x10E: |
|
| 2826 |
+ timer3Value = value; |
|
| 2827 |
+ timerOnOffDelay|=8; |
|
| 2828 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2829 |
+ break; |
|
| 2830 |
+ |
|
| 2831 |
+ |
|
| 2832 |
+ /*case COMM_SIOCNT: |
|
| 2833 |
+ StartLink(value); |
|
| 2834 |
+ break; |
|
| 2835 |
+ |
|
| 2836 |
+ case COMM_SIODATA8: |
|
| 2837 |
+ if (gba_link_enabled) |
|
| 2838 |
+ LinkSSend(value); |
|
| 2839 |
+ UPDATE_REG(COMM_SIODATA8, value); |
|
| 2840 |
+ break;*/ |
|
| 2841 |
+ |
|
| 2842 |
+ case 0x130: |
|
| 2843 |
+ P1 |= (value & 0x3FF); |
|
| 2844 |
+ UPDATE_REG(0x130, P1); |
|
| 2845 |
+ break; |
|
| 2846 |
+ |
|
| 2847 |
+ case 0x132: |
|
| 2848 |
+ UPDATE_REG(0x132, value & 0xC3FF); |
|
| 2849 |
+ break; |
|
| 2850 |
+ |
|
| 2851 |
+ /*case COMM_RCNT: |
|
| 2852 |
+ StartGPLink(value); |
|
| 2853 |
+ break; |
|
| 2854 |
+ |
|
| 2855 |
+ case COMM_JOYCNT: |
|
| 2856 |
+ {
|
|
| 2857 |
+ u16 cur = READ16LE(&ioMem[COMM_JOYCNT]); |
|
| 2858 |
+ |
|
| 2859 |
+ if (value & JOYCNT_RESET) cur &= ~JOYCNT_RESET; |
|
| 2860 |
+ if (value & JOYCNT_RECV_COMPLETE) cur &= ~JOYCNT_RECV_COMPLETE; |
|
| 2861 |
+ if (value & JOYCNT_SEND_COMPLETE) cur &= ~JOYCNT_SEND_COMPLETE; |
|
| 2862 |
+ if (value & JOYCNT_INT_ENABLE) cur |= JOYCNT_INT_ENABLE; |
|
| 2863 |
+ |
|
| 2864 |
+ UPDATE_REG(COMM_JOYCNT, cur); |
|
| 2865 |
+ } |
|
| 2866 |
+ break; |
|
| 2867 |
+ |
|
| 2868 |
+ case COMM_JOY_RECV_L: |
|
| 2869 |
+ UPDATE_REG(COMM_JOY_RECV_L, value); |
|
| 2870 |
+ break; |
|
| 2871 |
+ case COMM_JOY_RECV_H: |
|
| 2872 |
+ UPDATE_REG(COMM_JOY_RECV_H, value); |
|
| 2873 |
+ break; |
|
| 2874 |
+ |
|
| 2875 |
+ case COMM_JOY_TRANS_L: |
|
| 2876 |
+ UPDATE_REG(COMM_JOY_TRANS_L, value); |
|
| 2877 |
+ UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND); |
|
| 2878 |
+ break; |
|
| 2879 |
+ case COMM_JOY_TRANS_H: |
|
| 2880 |
+ UPDATE_REG(COMM_JOY_TRANS_H, value); |
|
| 2881 |
+ break; |
|
| 2882 |
+ |
|
| 2883 |
+ case COMM_JOYSTAT: |
|
| 2884 |
+ UPDATE_REG(COMM_JOYSTAT, (READ16LE(&ioMem[COMM_JOYSTAT]) & 0xf) | (value & 0xf0)); |
|
| 2885 |
+ break;*/ |
|
| 2886 |
+ |
|
| 2887 |
+ case 0x200: |
|
| 2888 |
+ IE = value & 0x3FFF; |
|
| 2889 |
+ UPDATE_REG(0x200, IE); |
|
| 2890 |
+ if ((IME & 1) && (IF & IE) && armIrqEnable) |
|
| 2891 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2892 |
+ break; |
|
| 2893 |
+ case 0x202: |
|
| 2894 |
+ IF ^= (value & IF); |
|
| 2895 |
+ UPDATE_REG(0x202, IF); |
|
| 2896 |
+ break; |
|
| 2897 |
+ case 0x204: |
|
| 2898 |
+ {
|
|
| 2899 |
+ memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3]; |
|
| 2900 |
+ |
|
| 2901 |
+ if(!speedHack) {
|
|
| 2902 |
+ memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3]; |
|
| 2903 |
+ memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = |
|
| 2904 |
+ gamepakWaitState0[(value >> 4) & 1]; |
|
| 2905 |
+ |
|
| 2906 |
+ memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3]; |
|
| 2907 |
+ memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = |
|
| 2908 |
+ gamepakWaitState1[(value >> 7) & 1]; |
|
| 2909 |
+ |
|
| 2910 |
+ memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3]; |
|
| 2911 |
+ memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = |
|
| 2912 |
+ gamepakWaitState2[(value >> 10) & 1]; |
|
| 2913 |
+ } else {
|
|
| 2914 |
+ memoryWait[0x08] = memoryWait[0x09] = 3; |
|
| 2915 |
+ memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = 1; |
|
| 2916 |
+ |
|
| 2917 |
+ memoryWait[0x0a] = memoryWait[0x0b] = 3; |
|
| 2918 |
+ memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = 1; |
|
| 2919 |
+ |
|
| 2920 |
+ memoryWait[0x0c] = memoryWait[0x0d] = 3; |
|
| 2921 |
+ memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = 1; |
|
| 2922 |
+ } |
|
| 2923 |
+ |
|
| 2924 |
+ for(int i = 8; i < 15; i++) {
|
|
| 2925 |
+ memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1; |
|
| 2926 |
+ memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1; |
|
| 2927 |
+ } |
|
| 2928 |
+ |
|
| 2929 |
+ if((value & 0x4000) == 0x4000) {
|
|
| 2930 |
+ busPrefetchEnable = true; |
|
| 2931 |
+ busPrefetch = false; |
|
| 2932 |
+ busPrefetchCount = 0; |
|
| 2933 |
+ } else {
|
|
| 2934 |
+ busPrefetchEnable = false; |
|
| 2935 |
+ busPrefetch = false; |
|
| 2936 |
+ busPrefetchCount = 0; |
|
| 2937 |
+ } |
|
| 2938 |
+ UPDATE_REG(0x204, value & 0x7FFF); |
|
| 2939 |
+ |
|
| 2940 |
+ } |
|
| 2941 |
+ break; |
|
| 2942 |
+ case 0x208: |
|
| 2943 |
+ IME = value & 1; |
|
| 2944 |
+ UPDATE_REG(0x208, IME); |
|
| 2945 |
+ if ((IME & 1) && (IF & IE) && armIrqEnable) |
|
| 2946 |
+ cpuNextEvent = cpuTotalTicks; |
|
| 2947 |
+ break; |
|
| 2948 |
+ case 0x300: |
|
| 2949 |
+ if(value != 0) |
|
| 2950 |
+ value &= 0xFFFE; |
|
| 2951 |
+ UPDATE_REG(0x300, value); |
|
| 2952 |
+ break; |
|
| 2953 |
+ default: |
|
| 2954 |
+ UPDATE_REG(address&0x3FE, value); |
|
| 2955 |
+ break; |
|
| 2956 |
+ } |
|
| 2957 |
+} |
|
| 2958 |
+ |
|
| 2959 |
+void applyTimer () |
|
| 2960 |
+{
|
|
| 2961 |
+ if (timerOnOffDelay & 1) |
|
| 2962 |
+ {
|
|
| 2963 |
+ timer0ClockReload = TIMER_TICKS[timer0Value & 3]; |
|
| 2964 |
+ if(!timer0On && (timer0Value & 0x80)) {
|
|
| 2965 |
+ // reload the counter |
|
| 2966 |
+ TM0D = timer0Reload; |
|
| 2967 |
+ timer0Ticks = (0x10000 - TM0D) << timer0ClockReload; |
|
| 2968 |
+ UPDATE_REG(0x100, TM0D); |
|
| 2969 |
+ } |
|
| 2970 |
+ timer0On = timer0Value & 0x80 ? true : false; |
|
| 2971 |
+ TM0CNT = timer0Value & 0xC7; |
|
| 2972 |
+ interp_rate(); |
|
| 2973 |
+ UPDATE_REG(0x102, TM0CNT); |
|
| 2974 |
+ // CPUUpdateTicks(); |
|
| 2975 |
+ } |
|
| 2976 |
+ if (timerOnOffDelay & 2) |
|
| 2977 |
+ {
|
|
| 2978 |
+ timer1ClockReload = TIMER_TICKS[timer1Value & 3]; |
|
| 2979 |
+ if(!timer1On && (timer1Value & 0x80)) {
|
|
| 2980 |
+ // reload the counter |
|
| 2981 |
+ TM1D = timer1Reload; |
|
| 2982 |
+ timer1Ticks = (0x10000 - TM1D) << timer1ClockReload; |
|
| 2983 |
+ UPDATE_REG(0x104, TM1D); |
|
| 2984 |
+ } |
|
| 2985 |
+ timer1On = timer1Value & 0x80 ? true : false; |
|
| 2986 |
+ TM1CNT = timer1Value & 0xC7; |
|
| 2987 |
+ interp_rate(); |
|
| 2988 |
+ UPDATE_REG(0x106, TM1CNT); |
|
| 2989 |
+ } |
|
| 2990 |
+ if (timerOnOffDelay & 4) |
|
| 2991 |
+ {
|
|
| 2992 |
+ timer2ClockReload = TIMER_TICKS[timer2Value & 3]; |
|
| 2993 |
+ if(!timer2On && (timer2Value & 0x80)) {
|
|
| 2994 |
+ // reload the counter |
|
| 2995 |
+ TM2D = timer2Reload; |
|
| 2996 |
+ timer2Ticks = (0x10000 - TM2D) << timer2ClockReload; |
|
| 2997 |
+ UPDATE_REG(0x108, TM2D); |
|
| 2998 |
+ } |
|
| 2999 |
+ timer2On = timer2Value & 0x80 ? true : false; |
|
| 3000 |
+ TM2CNT = timer2Value & 0xC7; |
|
| 3001 |
+ UPDATE_REG(0x10A, TM2CNT); |
|
| 3002 |
+ } |
|
| 3003 |
+ if (timerOnOffDelay & 8) |
|
| 3004 |
+ {
|
|
| 3005 |
+ timer3ClockReload = TIMER_TICKS[timer3Value & 3]; |
|
| 3006 |
+ if(!timer3On && (timer3Value & 0x80)) {
|
|
| 3007 |
+ // reload the counter |
|
| 3008 |
+ TM3D = timer3Reload; |
|
| 3009 |
+ timer3Ticks = (0x10000 - TM3D) << timer3ClockReload; |
|
| 3010 |
+ UPDATE_REG(0x10C, TM3D); |
|
| 3011 |
+ } |
|
| 3012 |
+ timer3On = timer3Value & 0x80 ? true : false; |
|
| 3013 |
+ TM3CNT = timer3Value & 0xC7; |
|
| 3014 |
+ UPDATE_REG(0x10E, TM3CNT); |
|
| 3015 |
+ } |
|
| 3016 |
+ cpuNextEvent = CPUUpdateTicks(); |
|
| 3017 |
+ timerOnOffDelay = 0; |
|
| 3018 |
+} |
|
| 3019 |
+ |
|
| 3020 |
+u8 cpuBitsSet[256]; |
|
| 3021 |
+u8 cpuLowestBitSet[256]; |
|
| 3022 |
+ |
|
| 3023 |
+void CPUInit(const char *biosFileName, bool useBiosFile) |
|
| 3024 |
+{
|
|
| 3025 |
+#ifdef WORDS_BIGENDIAN |
|
| 3026 |
+ if(!cpuBiosSwapped) {
|
|
| 3027 |
+ for(unsigned int i = 0; i < sizeof(myROM)/4; i++) {
|
|
| 3028 |
+ WRITE32LE(&myROM[i], myROM[i]); |
|
| 3029 |
+ } |
|
| 3030 |
+ cpuBiosSwapped = true; |
|
| 3031 |
+ } |
|
| 3032 |
+#endif |
|
| 3033 |
+ gbaSaveType = 0; |
|
| 3034 |
+ //eepromInUse = 0; |
|
| 3035 |
+ saveType = 0; |
|
| 3036 |
+ useBios = false; |
|
| 3037 |
+ |
|
| 3038 |
+ /*if(useBiosFile) {
|
|
| 3039 |
+ int size = 0x4000; |
|
| 3040 |
+ if(utilLoad(biosFileName, |
|
| 3041 |
+ CPUIsGBABios, |
|
| 3042 |
+ bios, |
|
| 3043 |
+ size)) {
|
|
| 3044 |
+ if(size == 0x4000) |
|
| 3045 |
+ useBios = true; |
|
| 3046 |
+ else |
|
| 3047 |
+ systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BIOS file size"));
|
|
| 3048 |
+ } |
|
| 3049 |
+ }*/ |
|
| 3050 |
+ |
|
| 3051 |
+ if(!useBios) {
|
|
| 3052 |
+ memcpy(bios, myROM, sizeof(myROM)); |
|
| 3053 |
+ } |
|
| 3054 |
+ |
|
| 3055 |
+ int i = 0; |
|
| 3056 |
+ |
|
| 3057 |
+ biosProtected[0] = 0x00; |
|
| 3058 |
+ biosProtected[1] = 0xf0; |
|
| 3059 |
+ biosProtected[2] = 0x29; |
|
| 3060 |
+ biosProtected[3] = 0xe1; |
|
| 3061 |
+ |
|
| 3062 |
+ for(i = 0; i < 256; i++) {
|
|
| 3063 |
+ int count = 0; |
|
| 3064 |
+ int j; |
|
| 3065 |
+ for(j = 0; j < 8; j++) |
|
| 3066 |
+ if(i & (1 << j)) |
|
| 3067 |
+ count++; |
|
| 3068 |
+ cpuBitsSet[i] = count; |
|
| 3069 |
+ |
|
| 3070 |
+ for(j = 0; j < 8; j++) |
|
| 3071 |
+ if(i & (1 << j)) |
|
| 3072 |
+ break; |
|
| 3073 |
+ cpuLowestBitSet[i] = j; |
|
| 3074 |
+ } |
|
| 3075 |
+ |
|
| 3076 |
+ for(i = 0; i < 0x400; i++) |
|
| 3077 |
+ ioReadable[i] = true; |
|
| 3078 |
+ for(i = 0x10; i < 0x48; i++) |
|
| 3079 |
+ ioReadable[i] = false; |
|
| 3080 |
+ for(i = 0x4c; i < 0x50; i++) |
|
| 3081 |
+ ioReadable[i] = false; |
|
| 3082 |
+ for(i = 0x54; i < 0x60; i++) |
|
| 3083 |
+ ioReadable[i] = false; |
|
| 3084 |
+ for(i = 0x8c; i < 0x90; i++) |
|
| 3085 |
+ ioReadable[i] = false; |
|
| 3086 |
+ for(i = 0xa0; i < 0xb8; i++) |
|
| 3087 |
+ ioReadable[i] = false; |
|
| 3088 |
+ for(i = 0xbc; i < 0xc4; i++) |
|
| 3089 |
+ ioReadable[i] = false; |
|
| 3090 |
+ for(i = 0xc8; i < 0xd0; i++) |
|
| 3091 |
+ ioReadable[i] = false; |
|
| 3092 |
+ for(i = 0xd4; i < 0xdc; i++) |
|
| 3093 |
+ ioReadable[i] = false; |
|
| 3094 |
+ for(i = 0xe0; i < 0x100; i++) |
|
| 3095 |
+ ioReadable[i] = false; |
|
| 3096 |
+ for(i = 0x110; i < 0x120; i++) |
|
| 3097 |
+ ioReadable[i] = false; |
|
| 3098 |
+ for(i = 0x12c; i < 0x130; i++) |
|
| 3099 |
+ ioReadable[i] = false; |
|
| 3100 |
+ for(i = 0x138; i < 0x140; i++) |
|
| 3101 |
+ ioReadable[i] = false; |
|
| 3102 |
+ for(i = 0x144; i < 0x150; i++) |
|
| 3103 |
+ ioReadable[i] = false; |
|
| 3104 |
+ for(i = 0x15c; i < 0x200; i++) |
|
| 3105 |
+ ioReadable[i] = false; |
|
| 3106 |
+ for(i = 0x20c; i < 0x300; i++) |
|
| 3107 |
+ ioReadable[i] = false; |
|
| 3108 |
+ for(i = 0x304; i < 0x400; i++) |
|
| 3109 |
+ ioReadable[i] = false; |
|
| 3110 |
+ |
|
| 3111 |
+ if(romSize < 0x1fe2000) {
|
|
| 3112 |
+ *((u16 *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA |
|
| 3113 |
+ *((u16 *)&rom[0x1fe209e]) = 0x4770; // BX LR |
|
| 3114 |
+ } else {
|
|
| 3115 |
+ //agbPrintEnable(false); |
|
| 3116 |
+ } |
|
| 3117 |
+} |
|
| 3118 |
+ |
|
| 3119 |
+void CPUReset() |
|
| 3120 |
+{
|
|
| 3121 |
+ /*if(gbaSaveType == 0) {
|
|
| 3122 |
+ if(eepromInUse) |
|
| 3123 |
+ gbaSaveType = 3; |
|
| 3124 |
+ else |
|
| 3125 |
+ switch(saveType) {
|
|
| 3126 |
+ case 1: |
|
| 3127 |
+ gbaSaveType = 1; |
|
| 3128 |
+ break; |
|
| 3129 |
+ case 2: |
|
| 3130 |
+ gbaSaveType = 2; |
|
| 3131 |
+ break; |
|
| 3132 |
+ } |
|
| 3133 |
+ } |
|
| 3134 |
+ rtcReset();*/ |
|
| 3135 |
+ // clean registers |
|
| 3136 |
+ memset(®[0], 0, sizeof(reg)); |
|
| 3137 |
+ // clean OAM |
|
| 3138 |
+ memset(oam, 0, 0x400); |
|
| 3139 |
+ // clean palette |
|
| 3140 |
+ memset(paletteRAM, 0, 0x400); |
|
| 3141 |
+ // clean picture |
|
| 3142 |
+ memset(pix, 0, 4*160*240); |
|
| 3143 |
+ // clean vram |
|
| 3144 |
+ memset(vram, 0, 0x20000); |
|
| 3145 |
+ // clean io memory |
|
| 3146 |
+ memset(ioMem, 0, 0x400); |
|
| 3147 |
+ |
|
| 3148 |
+ DISPCNT = 0x0080; |
|
| 3149 |
+ DISPSTAT = 0x0000; |
|
| 3150 |
+ VCOUNT = (useBios && !skipBios) ? 0 :0x007E; |
|
| 3151 |
+ BG0CNT = 0x0000; |
|
| 3152 |
+ BG1CNT = 0x0000; |
|
| 3153 |
+ BG2CNT = 0x0000; |
|
| 3154 |
+ BG3CNT = 0x0000; |
|
| 3155 |
+ BG0HOFS = 0x0000; |
|
| 3156 |
+ BG0VOFS = 0x0000; |
|
| 3157 |
+ BG1HOFS = 0x0000; |
|
| 3158 |
+ BG1VOFS = 0x0000; |
|
| 3159 |
+ BG2HOFS = 0x0000; |
|
| 3160 |
+ BG2VOFS = 0x0000; |
|
| 3161 |
+ BG3HOFS = 0x0000; |
|
| 3162 |
+ BG3VOFS = 0x0000; |
|
| 3163 |
+ BG2PA = 0x0100; |
|
| 3164 |
+ BG2PB = 0x0000; |
|
| 3165 |
+ BG2PC = 0x0000; |
|
| 3166 |
+ BG2PD = 0x0100; |
|
| 3167 |
+ BG2X_L = 0x0000; |
|
| 3168 |
+ BG2X_H = 0x0000; |
|
| 3169 |
+ BG2Y_L = 0x0000; |
|
| 3170 |
+ BG2Y_H = 0x0000; |
|
| 3171 |
+ BG3PA = 0x0100; |
|
| 3172 |
+ BG3PB = 0x0000; |
|
| 3173 |
+ BG3PC = 0x0000; |
|
| 3174 |
+ BG3PD = 0x0100; |
|
| 3175 |
+ BG3X_L = 0x0000; |
|
| 3176 |
+ BG3X_H = 0x0000; |
|
| 3177 |
+ BG3Y_L = 0x0000; |
|
| 3178 |
+ BG3Y_H = 0x0000; |
|
| 3179 |
+ WIN0H = 0x0000; |
|
| 3180 |
+ WIN1H = 0x0000; |
|
| 3181 |
+ WIN0V = 0x0000; |
|
| 3182 |
+ WIN1V = 0x0000; |
|
| 3183 |
+ WININ = 0x0000; |
|
| 3184 |
+ WINOUT = 0x0000; |
|
| 3185 |
+ MOSAIC = 0x0000; |
|
| 3186 |
+ BLDMOD = 0x0000; |
|
| 3187 |
+ COLEV = 0x0000; |
|
| 3188 |
+ COLY = 0x0000; |
|
| 3189 |
+ DM0SAD_L = 0x0000; |
|
| 3190 |
+ DM0SAD_H = 0x0000; |
|
| 3191 |
+ DM0DAD_L = 0x0000; |
|
| 3192 |
+ DM0DAD_H = 0x0000; |
|
| 3193 |
+ DM0CNT_L = 0x0000; |
|
| 3194 |
+ DM0CNT_H = 0x0000; |
|
| 3195 |
+ DM1SAD_L = 0x0000; |
|
| 3196 |
+ DM1SAD_H = 0x0000; |
|
| 3197 |
+ DM1DAD_L = 0x0000; |
|
| 3198 |
+ DM1DAD_H = 0x0000; |
|
| 3199 |
+ DM1CNT_L = 0x0000; |
|
| 3200 |
+ DM1CNT_H = 0x0000; |
|
| 3201 |
+ DM2SAD_L = 0x0000; |
|
| 3202 |
+ DM2SAD_H = 0x0000; |
|
| 3203 |
+ DM2DAD_L = 0x0000; |
|
| 3204 |
+ DM2DAD_H = 0x0000; |
|
| 3205 |
+ DM2CNT_L = 0x0000; |
|
| 3206 |
+ DM2CNT_H = 0x0000; |
|
| 3207 |
+ DM3SAD_L = 0x0000; |
|
| 3208 |
+ DM3SAD_H = 0x0000; |
|
| 3209 |
+ DM3DAD_L = 0x0000; |
|
| 3210 |
+ DM3DAD_H = 0x0000; |
|
| 3211 |
+ DM3CNT_L = 0x0000; |
|
| 3212 |
+ DM3CNT_H = 0x0000; |
|
| 3213 |
+ TM0D = 0x0000; |
|
| 3214 |
+ TM0CNT = 0x0000; |
|
| 3215 |
+ TM1D = 0x0000; |
|
| 3216 |
+ TM1CNT = 0x0000; |
|
| 3217 |
+ TM2D = 0x0000; |
|
| 3218 |
+ TM2CNT = 0x0000; |
|
| 3219 |
+ TM3D = 0x0000; |
|
| 3220 |
+ TM3CNT = 0x0000; |
|
| 3221 |
+ P1 = 0x03FF; |
|
| 3222 |
+ IE = 0x0000; |
|
| 3223 |
+ IF = 0x0000; |
|
| 3224 |
+ IME = 0x0000; |
|
| 3225 |
+ |
|
| 3226 |
+ armMode = 0x1F; |
|
| 3227 |
+ |
|
| 3228 |
+ if(cpuIsMultiBoot) {
|
|
| 3229 |
+ reg[13].I = 0x03007F00; |
|
| 3230 |
+ reg[15].I = 0x02000000; |
|
| 3231 |
+ reg[16].I = 0x00000000; |
|
| 3232 |
+ reg[R13_IRQ].I = 0x03007FA0; |
|
| 3233 |
+ reg[R13_SVC].I = 0x03007FE0; |
|
| 3234 |
+ armIrqEnable = true; |
|
| 3235 |
+ } else {
|
|
| 3236 |
+ if(useBios && !skipBios) {
|
|
| 3237 |
+ reg[15].I = 0x00000000; |
|
| 3238 |
+ armMode = 0x13; |
|
| 3239 |
+ armIrqEnable = false; |
|
| 3240 |
+ } else {
|
|
| 3241 |
+ reg[13].I = 0x03007F00; |
|
| 3242 |
+ reg[15].I = 0x08000000; |
|
| 3243 |
+ reg[16].I = 0x00000000; |
|
| 3244 |
+ reg[R13_IRQ].I = 0x03007FA0; |
|
| 3245 |
+ reg[R13_SVC].I = 0x03007FE0; |
|
| 3246 |
+ armIrqEnable = true; |
|
| 3247 |
+ } |
|
| 3248 |
+ } |
|
| 3249 |
+ armState = true; |
|
| 3250 |
+ C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false; |
|
| 3251 |
+ UPDATE_REG(0x00, DISPCNT); |
|
| 3252 |
+ UPDATE_REG(0x06, VCOUNT); |
|
| 3253 |
+ UPDATE_REG(0x20, BG2PA); |
|
| 3254 |
+ UPDATE_REG(0x26, BG2PD); |
|
| 3255 |
+ UPDATE_REG(0x30, BG3PA); |
|
| 3256 |
+ UPDATE_REG(0x36, BG3PD); |
|
| 3257 |
+ UPDATE_REG(0x130, P1); |
|
| 3258 |
+ UPDATE_REG(0x88, 0x200); |
|
| 3259 |
+ |
|
| 3260 |
+ // disable FIQ |
|
| 3261 |
+ reg[16].I |= 0x40; |
|
| 3262 |
+ |
|
| 3263 |
+ CPUUpdateCPSR(); |
|
| 3264 |
+ |
|
| 3265 |
+ armNextPC = reg[15].I; |
|
| 3266 |
+ reg[15].I += 4; |
|
| 3267 |
+ |
|
| 3268 |
+ // reset internal state |
|
| 3269 |
+ holdState = false; |
|
| 3270 |
+ holdType = 0; |
|
| 3271 |
+ |
|
| 3272 |
+ biosProtected[0] = 0x00; |
|
| 3273 |
+ biosProtected[1] = 0xf0; |
|
| 3274 |
+ biosProtected[2] = 0x29; |
|
| 3275 |
+ biosProtected[3] = 0xe1; |
|
| 3276 |
+ |
|
| 3277 |
+ lcdTicks = (useBios && !skipBios) ? 1008 : 208; |
|
| 3278 |
+ timer0On = false; |
|
| 3279 |
+ timer0Ticks = 0; |
|
| 3280 |
+ timer0Reload = 0; |
|
| 3281 |
+ timer0ClockReload = 0; |
|
| 3282 |
+ timer1On = false; |
|
| 3283 |
+ timer1Ticks = 0; |
|
| 3284 |
+ timer1Reload = 0; |
|
| 3285 |
+ timer1ClockReload = 0; |
|
| 3286 |
+ timer2On = false; |
|
| 3287 |
+ timer2Ticks = 0; |
|
| 3288 |
+ timer2Reload = 0; |
|
| 3289 |
+ timer2ClockReload = 0; |
|
| 3290 |
+ timer3On = false; |
|
| 3291 |
+ timer3Ticks = 0; |
|
| 3292 |
+ timer3Reload = 0; |
|
| 3293 |
+ timer3ClockReload = 0; |
|
| 3294 |
+ dma0Source = 0; |
|
| 3295 |
+ dma0Dest = 0; |
|
| 3296 |
+ dma1Source = 0; |
|
| 3297 |
+ dma1Dest = 0; |
|
| 3298 |
+ dma2Source = 0; |
|
| 3299 |
+ dma2Dest = 0; |
|
| 3300 |
+ dma3Source = 0; |
|
| 3301 |
+ dma3Dest = 0; |
|
| 3302 |
+ //cpuSaveGameFunc = flashSaveDecide; |
|
| 3303 |
+ //renderLine = mode0RenderLine; |
|
| 3304 |
+ fxOn = false; |
|
| 3305 |
+ windowOn = false; |
|
| 3306 |
+ frameCount = 0; |
|
| 3307 |
+ saveType = 0; |
|
| 3308 |
+ layerEnable = DISPCNT & layerSettings; |
|
| 3309 |
+ |
|
| 3310 |
+ //CPUUpdateRenderBuffers(true); |
|
| 3311 |
+ |
|
| 3312 |
+ for(int i = 0; i < 256; i++) {
|
|
| 3313 |
+ map[i].address = (u8 *)&dummyAddress; |
|
| 3314 |
+ map[i].mask = 0; |
|
| 3315 |
+ } |
|
| 3316 |
+ |
|
| 3317 |
+ map[0].address = bios; |
|
| 3318 |
+ map[0].mask = 0x3FFF; |
|
| 3319 |
+ map[2].address = workRAM; |
|
| 3320 |
+ map[2].mask = 0x3FFFF; |
|
| 3321 |
+ map[3].address = internalRAM; |
|
| 3322 |
+ map[3].mask = 0x7FFF; |
|
| 3323 |
+ map[4].address = ioMem; |
|
| 3324 |
+ map[4].mask = 0x3FF; |
|
| 3325 |
+ map[5].address = paletteRAM; |
|
| 3326 |
+ map[5].mask = 0x3FF; |
|
| 3327 |
+ map[6].address = vram; |
|
| 3328 |
+ map[6].mask = 0x1FFFF; |
|
| 3329 |
+ map[7].address = oam; |
|
| 3330 |
+ map[7].mask = 0x3FF; |
|
| 3331 |
+ map[8].address = rom; |
|
| 3332 |
+ map[8].mask = 0x1FFFFFF; |
|
| 3333 |
+ map[9].address = rom; |
|
| 3334 |
+ map[9].mask = 0x1FFFFFF; |
|
| 3335 |
+ map[10].address = rom; |
|
| 3336 |
+ map[10].mask = 0x1FFFFFF; |
|
| 3337 |
+ map[12].address = rom; |
|
| 3338 |
+ map[12].mask = 0x1FFFFFF; |
|
| 3339 |
+ map[14].address = /*flashSaveMemory*/0; |
|
| 3340 |
+ map[14].mask = 0xFFFF; |
|
| 3341 |
+ |
|
| 3342 |
+ //eepromReset(); |
|
| 3343 |
+ //flashReset(); |
|
| 3344 |
+ |
|
| 3345 |
+ soundReset(); |
|
| 3346 |
+ |
|
| 3347 |
+ //CPUUpdateWindow0(); |
|
| 3348 |
+ //CPUUpdateWindow1(); |
|
| 3349 |
+ |
|
| 3350 |
+ // make sure registers are correctly initialized if not using BIOS |
|
| 3351 |
+ if(!useBios) {
|
|
| 3352 |
+ if(cpuIsMultiBoot) |
|
| 3353 |
+ BIOS_RegisterRamReset(0xfe); |
|
| 3354 |
+ else |
|
| 3355 |
+ BIOS_RegisterRamReset(0xff); |
|
| 3356 |
+ } else {
|
|
| 3357 |
+ if(cpuIsMultiBoot) |
|
| 3358 |
+ BIOS_RegisterRamReset(0xfe); |
|
| 3359 |
+ } |
|
| 3360 |
+ |
|
| 3361 |
+ /*switch(cpuSaveType) {
|
|
| 3362 |
+ case 0: // automatic |
|
| 3363 |
+ cpuSramEnabled = true; |
|
| 3364 |
+ cpuFlashEnabled = true; |
|
| 3365 |
+ cpuEEPROMEnabled = true; |
|
| 3366 |
+ cpuEEPROMSensorEnabled = false; |
|
| 3367 |
+ saveType = gbaSaveType = 0; |
|
| 3368 |
+ break; |
|
| 3369 |
+ case 1: // EEPROM |
|
| 3370 |
+ cpuSramEnabled = false; |
|
| 3371 |
+ cpuFlashEnabled = false; |
|
| 3372 |
+ cpuEEPROMEnabled = true; |
|
| 3373 |
+ cpuEEPROMSensorEnabled = false; |
|
| 3374 |
+ saveType = gbaSaveType = 3; |
|
| 3375 |
+ // EEPROM usage is automatically detected |
|
| 3376 |
+ break; |
|
| 3377 |
+ case 2: // SRAM |
|
| 3378 |
+ cpuSramEnabled = true; |
|
| 3379 |
+ cpuFlashEnabled = false; |
|
| 3380 |
+ cpuEEPROMEnabled = false; |
|
| 3381 |
+ cpuEEPROMSensorEnabled = false; |
|
| 3382 |
+ cpuSaveGameFunc = sramDelayedWrite; // to insure we detect the write |
|
| 3383 |
+ saveType = gbaSaveType = 1; |
|
| 3384 |
+ break; |
|
| 3385 |
+ case 3: // FLASH |
|
| 3386 |
+ cpuSramEnabled = false; |
|
| 3387 |
+ cpuFlashEnabled = true; |
|
| 3388 |
+ cpuEEPROMEnabled = false; |
|
| 3389 |
+ cpuEEPROMSensorEnabled = false; |
|
| 3390 |
+ cpuSaveGameFunc = flashDelayedWrite; // to insure we detect the write |
|
| 3391 |
+ saveType = gbaSaveType = 2; |
|
| 3392 |
+ break; |
|
| 3393 |
+ case 4: // EEPROM+Sensor |
|
| 3394 |
+ cpuSramEnabled = false; |
|
| 3395 |
+ cpuFlashEnabled = false; |
|
| 3396 |
+ cpuEEPROMEnabled = true; |
|
| 3397 |
+ cpuEEPROMSensorEnabled = true; |
|
| 3398 |
+ // EEPROM usage is automatically detected |
|
| 3399 |
+ saveType = gbaSaveType = 3; |
|
| 3400 |
+ break; |
|
| 3401 |
+ case 5: // NONE |
|
| 3402 |
+ cpuSramEnabled = false; |
|
| 3403 |
+ cpuFlashEnabled = false; |
|
| 3404 |
+ cpuEEPROMEnabled = false; |
|
| 3405 |
+ cpuEEPROMSensorEnabled = false; |
|
| 3406 |
+ // no save at all |
|
| 3407 |
+ saveType = gbaSaveType = 5; |
|
| 3408 |
+ break; |
|
| 3409 |
+ }*/ |
|
| 3410 |
+ |
|
| 3411 |
+ ARM_PREFETCH; |
|
| 3412 |
+ |
|
| 3413 |
+ //systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
|
| 3414 |
+ |
|
| 3415 |
+ cpuDmaHack = false; |
|
| 3416 |
+ |
|
| 3417 |
+ lastTime = /*systemGetClock()*/0; |
|
| 3418 |
+ |
|
| 3419 |
+ SWITicks = 0; |
|
| 3420 |
+} |
|
| 3421 |
+ |
|
| 3422 |
+void CPUInterrupt() |
|
| 3423 |
+{
|
|
| 3424 |
+ u32 PC = reg[15].I; |
|
| 3425 |
+ bool savedState = armState; |
|
| 3426 |
+ CPUSwitchMode(0x12, true, false); |
|
| 3427 |
+ reg[14].I = PC; |
|
| 3428 |
+ if(!savedState) |
|
| 3429 |
+ reg[14].I += 2; |
|
| 3430 |
+ reg[15].I = 0x18; |
|
| 3431 |
+ armState = true; |
|
| 3432 |
+ armIrqEnable = false; |
|
| 3433 |
+ |
|
| 3434 |
+ armNextPC = reg[15].I; |
|
| 3435 |
+ reg[15].I += 4; |
|
| 3436 |
+ ARM_PREFETCH; |
|
| 3437 |
+ |
|
| 3438 |
+ // if(!holdState) |
|
| 3439 |
+ biosProtected[0] = 0x02; |
|
| 3440 |
+ biosProtected[1] = 0xc0; |
|
| 3441 |
+ biosProtected[2] = 0x5e; |
|
| 3442 |
+ biosProtected[3] = 0xe5; |
|
| 3443 |
+} |
|
| 3444 |
+ |
|
| 3445 |
+void CPULoop(int ticks) |
|
| 3446 |
+{
|
|
| 3447 |
+ int clockTicks; |
|
| 3448 |
+ int timerOverflow = 0; |
|
| 3449 |
+ // variable used by the CPU core |
|
| 3450 |
+ cpuTotalTicks = 0; |
|
| 3451 |
+ |
|
| 3452 |
+ // shuffle2: what's the purpose? |
|
| 3453 |
+ /*if(gba_link_enabled) |
|
| 3454 |
+ cpuNextEvent = 1;*/ |
|
| 3455 |
+ |
|
| 3456 |
+ cpuBreakLoop = false; |
|
| 3457 |
+ cpuNextEvent = CPUUpdateTicks(); |
|
| 3458 |
+ if(cpuNextEvent > ticks) |
|
| 3459 |
+ cpuNextEvent = ticks; |
|
| 3460 |
+ |
|
| 3461 |
+ |
|
| 3462 |
+ for(;;) {
|
|
| 3463 |
+#ifndef FINAL_VERSION |
|
| 3464 |
+ if(systemDebug) {
|
|
| 3465 |
+ if(systemDebug >= 10 && !holdState) {
|
|
| 3466 |
+ CPUUpdateCPSR(); |
|
| 3467 |
+#ifdef BKPT_SUPPORT |
|
| 3468 |
+ if (debugger_last) |
|
| 3469 |
+ {
|
|
| 3470 |
+ winlog("R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
|
|
| 3471 |
+ oldreg[0], oldreg[1], oldreg[2], oldreg[3], oldreg[4], oldreg[5], |
|
| 3472 |
+ oldreg[6], oldreg[7], oldreg[8], oldreg[9], oldreg[10], oldreg[11], |
|
| 3473 |
+ oldreg[12], oldreg[13], oldreg[14], oldreg[15], oldreg[16], |
|
| 3474 |
+ oldreg[17]); |
|
| 3475 |
+ } |
|
| 3476 |
+#endif |
|
| 3477 |
+ winlog("R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
|
|
| 3478 |
+ reg[0].I, reg[1].I, reg[2].I, reg[3].I, reg[4].I, reg[5].I, |
|
| 3479 |
+ reg[6].I, reg[7].I, reg[8].I, reg[9].I, reg[10].I, reg[11].I, |
|
| 3480 |
+ reg[12].I, reg[13].I, reg[14].I, reg[15].I, reg[16].I, |
|
| 3481 |
+ reg[17].I); |
|
| 3482 |
+ } else if(!holdState) {
|
|
| 3483 |
+ winlog("PC=%08x\n", armNextPC);
|
|
| 3484 |
+ } |
|
| 3485 |
+ } |
|
| 3486 |
+#endif /* FINAL_VERSION */ |
|
| 3487 |
+ |
|
| 3488 |
+ if(!holdState && !SWITicks) {
|
|
| 3489 |
+ if(armState) {
|
|
| 3490 |
+ if (!armExecute()) |
|
| 3491 |
+ return; |
|
| 3492 |
+ } else {
|
|
| 3493 |
+ if (!thumbExecute()) |
|
| 3494 |
+ return; |
|
| 3495 |
+ } |
|
| 3496 |
+ clockTicks = 0; |
|
| 3497 |
+ } else |
|
| 3498 |
+ clockTicks = CPUUpdateTicks(); |
|
| 3499 |
+ |
|
| 3500 |
+ cpuTotalTicks += clockTicks; |
|
| 3501 |
+ |
|
| 3502 |
+ |
|
| 3503 |
+ if(cpuTotalTicks >= cpuNextEvent) {
|
|
| 3504 |
+ int remainingTicks = cpuTotalTicks - cpuNextEvent; |
|
| 3505 |
+ |
|
| 3506 |
+ if (SWITicks) |
|
| 3507 |
+ {
|
|
| 3508 |
+ SWITicks-=clockTicks; |
|
| 3509 |
+ if (SWITicks<0) |
|
| 3510 |
+ SWITicks = 0; |
|
| 3511 |
+ } |
|
| 3512 |
+ |
|
| 3513 |
+ clockTicks = cpuNextEvent; |
|
| 3514 |
+ cpuTotalTicks = 0; |
|
| 3515 |
+ cpuDmaHack = false; |
|
| 3516 |
+ |
|
| 3517 |
+ updateLoop: |
|
| 3518 |
+ |
|
| 3519 |
+ if (IRQTicks) |
|
| 3520 |
+ {
|
|
| 3521 |
+ IRQTicks -= clockTicks; |
|
| 3522 |
+ if (IRQTicks<0) |
|
| 3523 |
+ IRQTicks = 0; |
|
| 3524 |
+ } |
|
| 3525 |
+ |
|
| 3526 |
+ lcdTicks -= clockTicks; |
|
| 3527 |
+ |
|
| 3528 |
+ |
|
| 3529 |
+ if(lcdTicks <= 0) {
|
|
| 3530 |
+ if(DISPSTAT & 1) { // V-BLANK
|
|
| 3531 |
+ // if in V-Blank mode, keep computing... |
|
| 3532 |
+ if(DISPSTAT & 2) {
|
|
| 3533 |
+ lcdTicks += 1008; |
|
| 3534 |
+ VCOUNT++; |
|
| 3535 |
+ UPDATE_REG(0x06, VCOUNT); |
|
| 3536 |
+ DISPSTAT &= 0xFFFD; |
|
| 3537 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 3538 |
+ CPUCompareVCOUNT(); |
|
| 3539 |
+ } else {
|
|
| 3540 |
+ lcdTicks += 224; |
|
| 3541 |
+ DISPSTAT |= 2; |
|
| 3542 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 3543 |
+ if(DISPSTAT & 16) {
|
|
| 3544 |
+ IF |= 2; |
|
| 3545 |
+ UPDATE_REG(0x202, IF); |
|
| 3546 |
+ } |
|
| 3547 |
+ } |
|
| 3548 |
+ |
|
| 3549 |
+ if(VCOUNT >= 228) { //Reaching last line
|
|
| 3550 |
+ DISPSTAT &= 0xFFFC; |
|
| 3551 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 3552 |
+ VCOUNT = 0; |
|
| 3553 |
+ UPDATE_REG(0x06, VCOUNT); |
|
| 3554 |
+ CPUCompareVCOUNT(); |
|
| 3555 |
+ } |
|
| 3556 |
+ } else {
|
|
| 3557 |
+ int framesToSkip = /*systemFrameSkip*/0; |
|
| 3558 |
+ if(speedup) |
|
| 3559 |
+ framesToSkip = 9; // try 6 FPS during speedup |
|
| 3560 |
+ |
|
| 3561 |
+ if(DISPSTAT & 2) {
|
|
| 3562 |
+ // if in H-Blank, leave it and move to drawing mode |
|
| 3563 |
+ VCOUNT++; |
|
| 3564 |
+ UPDATE_REG(0x06, VCOUNT); |
|
| 3565 |
+ |
|
| 3566 |
+ lcdTicks += 1008; |
|
| 3567 |
+ DISPSTAT &= 0xFFFD; |
|
| 3568 |
+ if(VCOUNT == 160) {
|
|
| 3569 |
+ count++; |
|
| 3570 |
+ //systemFrame(); |
|
| 3571 |
+ |
|
| 3572 |
+ if((count % 10) == 0) {
|
|
| 3573 |
+ //system10Frames(60); |
|
| 3574 |
+ } |
|
| 3575 |
+ if(count == 60) {
|
|
| 3576 |
+ u32 time = /*systemGetClock()*/0; |
|
| 3577 |
+ if(time != lastTime) {
|
|
| 3578 |
+ u32 t = 100000/(time - lastTime); |
|
| 3579 |
+ //systemShowSpeed(t); |
|
| 3580 |
+ } else |
|
| 3581 |
+ //systemShowSpeed(0); |
|
| 3582 |
+ lastTime = time; |
|
| 3583 |
+ count = 0; |
|
| 3584 |
+ } |
|
| 3585 |
+ u32 joy = 0; |
|
| 3586 |
+ // update joystick information |
|
| 3587 |
+ /*if(systemReadJoypads()) |
|
| 3588 |
+ // read default joystick |
|
| 3589 |
+ joy = systemReadJoypad(-1);*/ |
|
| 3590 |
+ P1 = 0x03FF ^ (joy & 0x3FF); |
|
| 3591 |
+ /*if(cpuEEPROMSensorEnabled) |
|
| 3592 |
+ systemUpdateMotionSensor();*/ |
|
| 3593 |
+ UPDATE_REG(0x130, P1); |
|
| 3594 |
+ u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132])); |
|
| 3595 |
+ // this seems wrong, but there are cases where the game |
|
| 3596 |
+ // can enter the stop state without requesting an IRQ from |
|
| 3597 |
+ // the joypad. |
|
| 3598 |
+ if((P1CNT & 0x4000) || stopState) {
|
|
| 3599 |
+ u16 p1 = (0x3FF ^ P1) & 0x3FF; |
|
| 3600 |
+ if(P1CNT & 0x8000) {
|
|
| 3601 |
+ if(p1 == (P1CNT & 0x3FF)) {
|
|
| 3602 |
+ IF |= 0x1000; |
|
| 3603 |
+ UPDATE_REG(0x202, IF); |
|
| 3604 |
+ } |
|
| 3605 |
+ } else {
|
|
| 3606 |
+ if(p1 & P1CNT) {
|
|
| 3607 |
+ IF |= 0x1000; |
|
| 3608 |
+ UPDATE_REG(0x202, IF); |
|
| 3609 |
+ } |
|
| 3610 |
+ } |
|
| 3611 |
+ } |
|
| 3612 |
+ |
|
| 3613 |
+ u32 ext = (joy >> 10); |
|
| 3614 |
+ // If no (m) code is enabled, apply the cheats at each LCDline |
|
| 3615 |
+ /*if((cheatsEnabled) && (mastercode==0)) |
|
| 3616 |
+ remainingTicks += cheatsCheckKeys(P1^0x3FF, ext);*/ |
|
| 3617 |
+ speedup = (ext & 1) ? true : false; |
|
| 3618 |
+ capture = (ext & 2) ? true : false; |
|
| 3619 |
+ |
|
| 3620 |
+ if(capture && !capturePrevious) {
|
|
| 3621 |
+ captureNumber++; |
|
| 3622 |
+ //systemScreenCapture(captureNumber); |
|
| 3623 |
+ } |
|
| 3624 |
+ capturePrevious = capture; |
|
| 3625 |
+ |
|
| 3626 |
+ DISPSTAT |= 1; |
|
| 3627 |
+ DISPSTAT &= 0xFFFD; |
|
| 3628 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 3629 |
+ if(DISPSTAT & 0x0008) {
|
|
| 3630 |
+ IF |= 1; |
|
| 3631 |
+ UPDATE_REG(0x202, IF); |
|
| 3632 |
+ } |
|
| 3633 |
+ CPUCheckDMA(1, 0x0f); |
|
| 3634 |
+ if(frameCount >= framesToSkip) {
|
|
| 3635 |
+ //systemDrawScreen(); |
|
| 3636 |
+ frameCount = 0; |
|
| 3637 |
+ } else |
|
| 3638 |
+ frameCount++; |
|
| 3639 |
+ /*if(systemPauseOnFrame()) |
|
| 3640 |
+ ticks = 0;*/ |
|
| 3641 |
+ } |
|
| 3642 |
+ |
|
| 3643 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 3644 |
+ CPUCompareVCOUNT(); |
|
| 3645 |
+ |
|
| 3646 |
+ } else {
|
|
| 3647 |
+ if(frameCount >= framesToSkip) |
|
| 3648 |
+ {
|
|
| 3649 |
+ /*(*renderLine)(); |
|
| 3650 |
+ switch(systemColorDepth) {
|
|
| 3651 |
+ case 16: |
|
| 3652 |
+ {
|
|
| 3653 |
+ u16 *dest = (u16 *)pix + 242 * (VCOUNT+1); |
|
| 3654 |
+ for(int x = 0; x < 240;) {
|
|
| 3655 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3656 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3657 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3658 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3659 |
+ |
|
| 3660 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3661 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3662 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3663 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3664 |
+ |
|
| 3665 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3666 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3667 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3668 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3669 |
+ |
|
| 3670 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3671 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3672 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3673 |
+ *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; |
|
| 3674 |
+ } |
|
| 3675 |
+ // for filters that read past the screen |
|
| 3676 |
+ *dest++ = 0; |
|
| 3677 |
+ } |
|
| 3678 |
+ break; |
|
| 3679 |
+ case 24: |
|
| 3680 |
+ {
|
|
| 3681 |
+ u8 *dest = (u8 *)pix + 240 * VCOUNT * 3; |
|
| 3682 |
+ for(int x = 0; x < 240;) {
|
|
| 3683 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3684 |
+ dest += 3; |
|
| 3685 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3686 |
+ dest += 3; |
|
| 3687 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3688 |
+ dest += 3; |
|
| 3689 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3690 |
+ dest += 3; |
|
| 3691 |
+ |
|
| 3692 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3693 |
+ dest += 3; |
|
| 3694 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3695 |
+ dest += 3; |
|
| 3696 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3697 |
+ dest += 3; |
|
| 3698 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3699 |
+ dest += 3; |
|
| 3700 |
+ |
|
| 3701 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3702 |
+ dest += 3; |
|
| 3703 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3704 |
+ dest += 3; |
|
| 3705 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3706 |
+ dest += 3; |
|
| 3707 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3708 |
+ dest += 3; |
|
| 3709 |
+ |
|
| 3710 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3711 |
+ dest += 3; |
|
| 3712 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3713 |
+ dest += 3; |
|
| 3714 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3715 |
+ dest += 3; |
|
| 3716 |
+ *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3717 |
+ dest += 3; |
|
| 3718 |
+ } |
|
| 3719 |
+ } |
|
| 3720 |
+ break; |
|
| 3721 |
+ case 32: |
|
| 3722 |
+ {
|
|
| 3723 |
+ u32 *dest = (u32 *)pix + 241 * (VCOUNT+1); |
|
| 3724 |
+ for(int x = 0; x < 240; ) {
|
|
| 3725 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3726 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3727 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3728 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3729 |
+ |
|
| 3730 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3731 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3732 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3733 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3734 |
+ |
|
| 3735 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3736 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3737 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3738 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3739 |
+ |
|
| 3740 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3741 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3742 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3743 |
+ *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; |
|
| 3744 |
+ } |
|
| 3745 |
+ } |
|
| 3746 |
+ break; |
|
| 3747 |
+ }*/ |
|
| 3748 |
+ } |
|
| 3749 |
+ // entering H-Blank |
|
| 3750 |
+ DISPSTAT |= 2; |
|
| 3751 |
+ UPDATE_REG(0x04, DISPSTAT); |
|
| 3752 |
+ lcdTicks += 224; |
|
| 3753 |
+ CPUCheckDMA(2, 0x0f); |
|
| 3754 |
+ if(DISPSTAT & 16) {
|
|
| 3755 |
+ IF |= 2; |
|
| 3756 |
+ UPDATE_REG(0x202, IF); |
|
| 3757 |
+ } |
|
| 3758 |
+ } |
|
| 3759 |
+ } |
|
| 3760 |
+ } |
|
| 3761 |
+ |
|
| 3762 |
+ // we shouldn't be doing sound in stop state, but we loose synchronization |
|
| 3763 |
+ // if sound is disabled, so in stop state, soundTick will just produce |
|
| 3764 |
+ // mute sound |
|
| 3765 |
+ soundTicks -= clockTicks; |
|
| 3766 |
+ if(soundTicks <= 0) {
|
|
| 3767 |
+ psoundTickfn(); |
|
| 3768 |
+ soundTicks += SOUND_CLOCK_TICKS; |
|
| 3769 |
+ } |
|
| 3770 |
+ |
|
| 3771 |
+ if(!stopState) {
|
|
| 3772 |
+ if(timer0On) {
|
|
| 3773 |
+ timer0Ticks -= clockTicks; |
|
| 3774 |
+ if(timer0Ticks <= 0) {
|
|
| 3775 |
+ timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload; |
|
| 3776 |
+ timerOverflow |= 1; |
|
| 3777 |
+ soundTimerOverflow(0); |
|
| 3778 |
+ if(TM0CNT & 0x40) {
|
|
| 3779 |
+ IF |= 0x08; |
|
| 3780 |
+ UPDATE_REG(0x202, IF); |
|
| 3781 |
+ } |
|
| 3782 |
+ } |
|
| 3783 |
+ TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload); |
|
| 3784 |
+ UPDATE_REG(0x100, TM0D); |
|
| 3785 |
+ } |
|
| 3786 |
+ |
|
| 3787 |
+ if(timer1On) {
|
|
| 3788 |
+ if(TM1CNT & 4) {
|
|
| 3789 |
+ if(timerOverflow & 1) {
|
|
| 3790 |
+ TM1D++; |
|
| 3791 |
+ if(TM1D == 0) {
|
|
| 3792 |
+ TM1D += timer1Reload; |
|
| 3793 |
+ timerOverflow |= 2; |
|
| 3794 |
+ soundTimerOverflow(1); |
|
| 3795 |
+ if(TM1CNT & 0x40) {
|
|
| 3796 |
+ IF |= 0x10; |
|
| 3797 |
+ UPDATE_REG(0x202, IF); |
|
| 3798 |
+ } |
|
| 3799 |
+ } |
|
| 3800 |
+ UPDATE_REG(0x104, TM1D); |
|
| 3801 |
+ } |
|
| 3802 |
+ } else {
|
|
| 3803 |
+ timer1Ticks -= clockTicks; |
|
| 3804 |
+ if(timer1Ticks <= 0) {
|
|
| 3805 |
+ timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload; |
|
| 3806 |
+ timerOverflow |= 2; |
|
| 3807 |
+ soundTimerOverflow(1); |
|
| 3808 |
+ if(TM1CNT & 0x40) {
|
|
| 3809 |
+ IF |= 0x10; |
|
| 3810 |
+ UPDATE_REG(0x202, IF); |
|
| 3811 |
+ } |
|
| 3812 |
+ } |
|
| 3813 |
+ TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload); |
|
| 3814 |
+ UPDATE_REG(0x104, TM1D); |
|
| 3815 |
+ } |
|
| 3816 |
+ } |
|
| 3817 |
+ |
|
| 3818 |
+ if(timer2On) {
|
|
| 3819 |
+ if(TM2CNT & 4) {
|
|
| 3820 |
+ if(timerOverflow & 2) {
|
|
| 3821 |
+ TM2D++; |
|
| 3822 |
+ if(TM2D == 0) {
|
|
| 3823 |
+ TM2D += timer2Reload; |
|
| 3824 |
+ timerOverflow |= 4; |
|
| 3825 |
+ if(TM2CNT & 0x40) {
|
|
| 3826 |
+ IF |= 0x20; |
|
| 3827 |
+ UPDATE_REG(0x202, IF); |
|
| 3828 |
+ } |
|
| 3829 |
+ } |
|
| 3830 |
+ UPDATE_REG(0x108, TM2D); |
|
| 3831 |
+ } |
|
| 3832 |
+ } else {
|
|
| 3833 |
+ timer2Ticks -= clockTicks; |
|
| 3834 |
+ if(timer2Ticks <= 0) {
|
|
| 3835 |
+ timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload; |
|
| 3836 |
+ timerOverflow |= 4; |
|
| 3837 |
+ if(TM2CNT & 0x40) {
|
|
| 3838 |
+ IF |= 0x20; |
|
| 3839 |
+ UPDATE_REG(0x202, IF); |
|
| 3840 |
+ } |
|
| 3841 |
+ } |
|
| 3842 |
+ TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload); |
|
| 3843 |
+ UPDATE_REG(0x108, TM2D); |
|
| 3844 |
+ } |
|
| 3845 |
+ } |
|
| 3846 |
+ |
|
| 3847 |
+ if(timer3On) {
|
|
| 3848 |
+ if(TM3CNT & 4) {
|
|
| 3849 |
+ if(timerOverflow & 4) {
|
|
| 3850 |
+ TM3D++; |
|
| 3851 |
+ if(TM3D == 0) {
|
|
| 3852 |
+ TM3D += timer3Reload; |
|
| 3853 |
+ if(TM3CNT & 0x40) {
|
|
| 3854 |
+ IF |= 0x40; |
|
| 3855 |
+ UPDATE_REG(0x202, IF); |
|
| 3856 |
+ } |
|
| 3857 |
+ } |
|
| 3858 |
+ UPDATE_REG(0x10C, TM3D); |
|
| 3859 |
+ } |
|
| 3860 |
+ } else {
|
|
| 3861 |
+ timer3Ticks -= clockTicks; |
|
| 3862 |
+ if(timer3Ticks <= 0) {
|
|
| 3863 |
+ timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload; |
|
| 3864 |
+ if(TM3CNT & 0x40) {
|
|
| 3865 |
+ IF |= 0x40; |
|
| 3866 |
+ UPDATE_REG(0x202, IF); |
|
| 3867 |
+ } |
|
| 3868 |
+ } |
|
| 3869 |
+ TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload); |
|
| 3870 |
+ UPDATE_REG(0x10C, TM3D); |
|
| 3871 |
+ } |
|
| 3872 |
+ } |
|
| 3873 |
+ } |
|
| 3874 |
+ |
|
| 3875 |
+ timerOverflow = 0; |
|
| 3876 |
+ |
|
| 3877 |
+ |
|
| 3878 |
+ |
|
| 3879 |
+#ifdef PROFILING |
|
| 3880 |
+ profilingTicks -= clockTicks; |
|
| 3881 |
+ if(profilingTicks <= 0) {
|
|
| 3882 |
+ profilingTicks += profilingTicksReload; |
|
| 3883 |
+ if(profilSegment) {
|
|
| 3884 |
+ profile_segment *seg = profilSegment; |
|
| 3885 |
+ do {
|
|
| 3886 |
+ u16 *b = (u16 *)seg->sbuf; |
|
| 3887 |
+ int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale)/0x10000; |
|
| 3888 |
+ if(pc >= 0 && pc < seg->ssiz) {
|
|
| 3889 |
+ b[pc]++; |
|
| 3890 |
+ break; |
|
| 3891 |
+ } |
|
| 3892 |
+ |
|
| 3893 |
+ seg = seg->next; |
|
| 3894 |
+ } while(seg); |
|
| 3895 |
+ } |
|
| 3896 |
+ } |
|
| 3897 |
+#endif |
|
| 3898 |
+ |
|
| 3899 |
+ ticks -= clockTicks; |
|
| 3900 |
+ |
|
| 3901 |
+ /*if (gba_joybus_enabled) |
|
| 3902 |
+ JoyBusUpdate(clockTicks); |
|
| 3903 |
+ |
|
| 3904 |
+ if (gba_link_enabled) |
|
| 3905 |
+ LinkUpdate(clockTicks);*/ |
|
| 3906 |
+ |
|
| 3907 |
+ cpuNextEvent = CPUUpdateTicks(); |
|
| 3908 |
+ |
|
| 3909 |
+ if(cpuDmaTicksToUpdate > 0) {
|
|
| 3910 |
+ if(cpuDmaTicksToUpdate > cpuNextEvent) |
|
| 3911 |
+ clockTicks = cpuNextEvent; |
|
| 3912 |
+ else |
|
| 3913 |
+ clockTicks = cpuDmaTicksToUpdate; |
|
| 3914 |
+ cpuDmaTicksToUpdate -= clockTicks; |
|
| 3915 |
+ if(cpuDmaTicksToUpdate < 0) |
|
| 3916 |
+ cpuDmaTicksToUpdate = 0; |
|
| 3917 |
+ cpuDmaHack = true; |
|
| 3918 |
+ goto updateLoop; |
|
| 3919 |
+ } |
|
| 3920 |
+ |
|
| 3921 |
+ // shuffle2: what's the purpose? |
|
| 3922 |
+ /*if(gba_link_enabled) |
|
| 3923 |
+ cpuNextEvent = 1;*/ |
|
| 3924 |
+ |
|
| 3925 |
+ if(IF && (IME & 1) && armIrqEnable) {
|
|
| 3926 |
+ int res = IF & IE; |
|
| 3927 |
+ if(stopState) |
|
| 3928 |
+ res &= 0x3080; |
|
| 3929 |
+ if(res) {
|
|
| 3930 |
+ if (intState) |
|
| 3931 |
+ {
|
|
| 3932 |
+ if (!IRQTicks) |
|
| 3933 |
+ {
|
|
| 3934 |
+ CPUInterrupt(); |
|
| 3935 |
+ intState = false; |
|
| 3936 |
+ holdState = false; |
|
| 3937 |
+ stopState = false; |
|
| 3938 |
+ holdType = 0; |
|
| 3939 |
+ } |
|
| 3940 |
+ } |
|
| 3941 |
+ else |
|
| 3942 |
+ {
|
|
| 3943 |
+ if (!holdState) |
|
| 3944 |
+ {
|
|
| 3945 |
+ intState = true; |
|
| 3946 |
+ IRQTicks=7; |
|
| 3947 |
+ if (cpuNextEvent> IRQTicks) |
|
| 3948 |
+ cpuNextEvent = IRQTicks; |
|
| 3949 |
+ } |
|
| 3950 |
+ else |
|
| 3951 |
+ {
|
|
| 3952 |
+ CPUInterrupt(); |
|
| 3953 |
+ holdState = false; |
|
| 3954 |
+ stopState = false; |
|
| 3955 |
+ holdType = 0; |
|
| 3956 |
+ } |
|
| 3957 |
+ } |
|
| 3958 |
+ |
|
| 3959 |
+ // Stops the SWI Ticks emulation if an IRQ is executed |
|
| 3960 |
+ //(to avoid problems with nested IRQ/SWI) |
|
| 3961 |
+ if (SWITicks) |
|
| 3962 |
+ SWITicks = 0; |
|
| 3963 |
+ } |
|
| 3964 |
+ } |
|
| 3965 |
+ |
|
| 3966 |
+ if(remainingTicks > 0) {
|
|
| 3967 |
+ if(remainingTicks > cpuNextEvent) |
|
| 3968 |
+ clockTicks = cpuNextEvent; |
|
| 3969 |
+ else |
|
| 3970 |
+ clockTicks = remainingTicks; |
|
| 3971 |
+ remainingTicks -= clockTicks; |
|
| 3972 |
+ if(remainingTicks < 0) |
|
| 3973 |
+ remainingTicks = 0; |
|
| 3974 |
+ goto updateLoop; |
|
| 3975 |
+ } |
|
| 3976 |
+ |
|
| 3977 |
+ if (timerOnOffDelay) |
|
| 3978 |
+ applyTimer(); |
|
| 3979 |
+ |
|
| 3980 |
+ if(cpuNextEvent > ticks) |
|
| 3981 |
+ cpuNextEvent = ticks; |
|
| 3982 |
+ |
|
| 3983 |
+ if(ticks <= 0 || cpuBreakLoop) |
|
| 3984 |
+ break; |
|
| 3985 |
+ |
|
| 3986 |
+ } |
|
| 3987 |
+ } |
|
| 3988 |
+} |
|
| 3989 |
+ |
|
| 3990 |
+ |
|
| 3991 |
+ |
|
| 3992 |
+/*struct EmulatedSystem GBASystem = {
|
|
| 3993 |
+ // emuMain |
|
| 3994 |
+ CPULoop, |
|
| 3995 |
+ // emuReset |
|
| 3996 |
+ CPUReset, |
|
| 3997 |
+ // emuCleanUp |
|
| 3998 |
+ CPUCleanUp, |
|
| 3999 |
+ // emuReadBattery |
|
| 4000 |
+ CPUReadBatteryFile, |
|
| 4001 |
+ // emuWriteBattery |
|
| 4002 |
+ CPUWriteBatteryFile, |
|
| 4003 |
+ // emuReadState |
|
| 4004 |
+ CPUReadState, |
|
| 4005 |
+ // emuWriteState |
|
| 4006 |
+ CPUWriteState, |
|
| 4007 |
+ // emuReadMemState |
|
| 4008 |
+ CPUReadMemState, |
|
| 4009 |
+ // emuWriteMemState |
|
| 4010 |
+ CPUWriteMemState, |
|
| 4011 |
+ // emuWritePNG |
|
| 4012 |
+ CPUWritePNGFile, |
|
| 4013 |
+ // emuWriteBMP |
|
| 4014 |
+ CPUWriteBMPFile, |
|
| 4015 |
+ // emuUpdateCPSR |
|
| 4016 |
+ CPUUpdateCPSR, |
|
| 4017 |
+ // emuHasDebugger |
|
| 4018 |
+ true, |
|
| 4019 |
+ // emuCount |
|
| 4020 |
+#ifdef FINAL_VERSION |
|
| 4021 |
+ 250000 |
|
| 4022 |
+#else |
|
| 4023 |
+ 5000 |
|
| 4024 |
+#endif |
|
| 4025 |
+};*/ |