mirror of https://github.com/mgba-emu/mgba.git
Implement waitstate adjusting
This commit is contained in:
parent
fe5a8d6254
commit
1838cc0597
|
@ -2,17 +2,24 @@
|
|||
|
||||
void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
||||
switch (address) {
|
||||
case REG_WAITCNT:
|
||||
GBAAdjustWaitstates(&gba->memory, value);
|
||||
break;
|
||||
default:
|
||||
GBALog(GBA_LOG_STUB, "Stub I/O register write: %03x", address);
|
||||
break;
|
||||
}
|
||||
gba->memory.io[address >> 1] = value;
|
||||
}
|
||||
|
||||
uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
||||
switch (address) {
|
||||
case REG_WAITCNT:
|
||||
// Handled transparently by registers
|
||||
break;
|
||||
default:
|
||||
GBALog(GBA_LOG_STUB, "Stub I/O register read: %03x", address);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return gba->memory.io[address >> 1];
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t region);
|
|||
|
||||
static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
|
||||
static const char GBA_BASE_WAITSTATES_SEQ[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4 };
|
||||
static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
|
||||
static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
|
||||
|
||||
void GBAMemoryInit(struct GBAMemory* memory) {
|
||||
memory->d.load32 = GBALoad32;
|
||||
|
@ -48,9 +50,12 @@ void GBAMemoryInit(struct GBAMemory* memory) {
|
|||
memory->waitstatesSeq32[i] = 0;
|
||||
}
|
||||
|
||||
memory->activeRegion = 0;
|
||||
memory->d.activeRegion = 0;
|
||||
memory->d.activeMask = 0;
|
||||
memory->d.setActiveRegion = GBASetActiveRegion;
|
||||
memory->d.activePrefetchCycles32 = 0;
|
||||
memory->d.activePrefetchCycles16 = 0;
|
||||
}
|
||||
|
||||
void GBAMemoryDeinit(struct GBAMemory* memory) {
|
||||
|
@ -63,6 +68,7 @@ static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t address) {
|
|||
|
||||
memory->activePrefetchCycles32 = gbaMemory->waitstates32[address >> BASE_OFFSET];
|
||||
memory->activePrefetchCycles16 = gbaMemory->waitstates16[address >> BASE_OFFSET];
|
||||
gbaMemory->activeRegion = address >> BASE_OFFSET;
|
||||
switch (address & ~OFFSET_MASK) {
|
||||
case BASE_BIOS:
|
||||
memory->activeRegion = gbaMemory->bios;
|
||||
|
@ -351,3 +357,38 @@ void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters) {
|
||||
int sram = parameters & 0x0003;
|
||||
int ws0 = (parameters & 0x000C) >> 2;
|
||||
int ws0seq = (parameters & 0x0010) >> 4;
|
||||
int ws1 = (parameters & 0x0060) >> 5;
|
||||
int ws1seq = (parameters & 0x0080) >> 7;
|
||||
int ws2 = (parameters & 0x0300) >> 8;
|
||||
int ws2seq = (parameters & 0x0400) >> 10;
|
||||
int prefetch = parameters & 0x4000;
|
||||
|
||||
memory->waitstates16[REGION_CART_SRAM] = GBA_ROM_WAITSTATES[sram];
|
||||
memory->waitstatesSeq16[REGION_CART_SRAM] = GBA_ROM_WAITSTATES[sram];
|
||||
memory->waitstates32[REGION_CART_SRAM] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
|
||||
memory->waitstatesSeq32[REGION_CART_SRAM] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
|
||||
|
||||
memory->waitstates16[REGION_CART0] = memory->waitstates16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
|
||||
memory->waitstates16[REGION_CART1] = memory->waitstates16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
|
||||
memory->waitstates16[REGION_CART2] = memory->waitstates16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
|
||||
|
||||
memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
|
||||
memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
|
||||
memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
|
||||
|
||||
memory->waitstates32[REGION_CART0] = memory->waitstates32[REGION_CART0_EX] = memory->waitstates16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
|
||||
memory->waitstates32[REGION_CART1] = memory->waitstates32[REGION_CART1_EX] = memory->waitstates16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
|
||||
memory->waitstates32[REGION_CART2] = memory->waitstates32[REGION_CART2_EX] = memory->waitstates16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
|
||||
|
||||
memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0 + 1] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
|
||||
memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1 + 1] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
|
||||
memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2 + 1] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
|
||||
|
||||
memory->d.activePrefetchCycles32 = memory->waitstates32[memory->activeRegion];
|
||||
memory->d.activePrefetchCycles16 = memory->waitstates16[memory->activeRegion];
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ struct GBAMemory {
|
|||
char waitstates16[256];
|
||||
char waitstatesSeq32[256];
|
||||
char waitstatesSeq16[256];
|
||||
int activeRegion;
|
||||
};
|
||||
|
||||
int32_t GBALoad32(struct ARMMemory* memory, uint32_t address);
|
||||
|
@ -85,4 +86,6 @@ void GBAStore32(struct ARMMemory* memory, uint32_t address, int32_t value);
|
|||
void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value);
|
||||
void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value);
|
||||
|
||||
void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,8 +17,6 @@ enum {
|
|||
|
||||
static void GBAHitStub(struct ARMBoard* board, uint32_t opcode);
|
||||
|
||||
static void _GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value);
|
||||
|
||||
void GBAInit(struct GBA* gba) {
|
||||
gba->errno = GBA_NO_ERROR;
|
||||
gba->errstr = 0;
|
||||
|
|
Loading…
Reference in New Issue