DS: Basic memory support for RAM

This commit is contained in:
Jeffrey Pfau 2016-06-01 20:21:00 -07:00
parent e93154fb41
commit 2006f27d6d
2 changed files with 87 additions and 13 deletions

View File

@ -129,6 +129,27 @@ void DS7Reset(struct ARMCore* cpu) {
cpu->gprs[ARM_SP] = DS7_SP_BASE_SVC; cpu->gprs[ARM_SP] = DS7_SP_BASE_SVC;
ARMSetPrivilegeMode(cpu, MODE_SYSTEM); ARMSetPrivilegeMode(cpu, MODE_SYSTEM);
cpu->gprs[ARM_SP] = DS7_SP_BASE; cpu->gprs[ARM_SP] = DS7_SP_BASE;
struct DS* ds = (struct DS*) cpu->master;
DSMemoryReset(ds);
struct DSCartridge* header = ds->romVf->map(ds->romVf, sizeof(*header), MAP_READ);
if (header) {
// TODO: Error check
ds->romVf->seek(ds->romVf, header->arm7Offset, SEEK_SET);
uint32_t base = header->arm7Base - DS_BASE_RAM;
uint32_t* basePointer = &ds->memory.ram[base >> 2];
if (base < DS_SIZE_RAM && base + header->arm7Size <= DS_SIZE_RAM) {
ds->romVf->read(ds->romVf, basePointer, header->arm7Size);
}
cpu->gprs[12] = header->arm7Entry;
cpu->gprs[ARM_LR] = header->arm7Entry;
cpu->gprs[ARM_PC] = header->arm7Entry;
int currentCycles = 0;
ARM_WRITE_PC;
ds->romVf->unmap(ds->romVf, header, sizeof(*header));
}
} }
void DS9Reset(struct ARMCore* cpu) { void DS9Reset(struct ARMCore* cpu) {
@ -140,7 +161,23 @@ void DS9Reset(struct ARMCore* cpu) {
cpu->gprs[ARM_SP] = DS9_SP_BASE; cpu->gprs[ARM_SP] = DS9_SP_BASE;
struct DS* ds = (struct DS*) cpu->master; struct DS* ds = (struct DS*) cpu->master;
DSMemoryReset(ds); struct DSCartridge* header = ds->romVf->map(ds->romVf, sizeof(*header), MAP_READ);
if (header) {
// TODO: Error check
ds->romVf->seek(ds->romVf, header->arm9Offset, SEEK_SET);
uint32_t base = header->arm9Base - DS_BASE_RAM;
uint32_t* basePointer = &ds->memory.ram[base >> 2];
if (base < DS_SIZE_RAM && base + header->arm9Size <= DS_SIZE_RAM) {
ds->romVf->read(ds->romVf, basePointer, header->arm9Size);
}
cpu->gprs[12] = header->arm9Entry;
cpu->gprs[ARM_LR] = header->arm9Entry;
cpu->gprs[ARM_PC] = header->arm9Entry;
int currentCycles = 0;
ARM_WRITE_PC;
ds->romVf->unmap(ds->romVf, header, sizeof(*header));
}
} }
static void DSProcessEvents(struct ARMCore* cpu) { static void DSProcessEvents(struct ARMCore* cpu) {
@ -189,7 +226,6 @@ void DSDetachDebugger(struct DS* ds) {
bool DSLoadROM(struct DS* ds, struct VFile* vf) { bool DSLoadROM(struct DS* ds, struct VFile* vf) {
DSUnloadROM(ds); DSUnloadROM(ds);
ds->romVf = vf; ds->romVf = vf;
// TODO: Checksum?
// TODO: error check // TODO: error check
return true; return true;
} }

View File

@ -5,8 +5,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "memory.h" #include "memory.h"
#include "arm/macros.h"
#include "ds/ds.h" #include "ds/ds.h"
#include "util/math.h" #include "util/math.h"
#include "util/memory.h"
mLOG_DEFINE_CATEGORY(DS_MEM, "DS Memory"); mLOG_DEFINE_CATEGORY(DS_MEM, "DS Memory");
@ -161,14 +164,29 @@ static void DS7SetActiveRegion(struct ARMCore* cpu, uint32_t address) {
memory->activeRegion7 = newRegion; memory->activeRegion7 = newRegion;
switch (newRegion) { switch (newRegion) {
case DS7_REGION_BIOS: case DS_REGION_RAM:
cpu->memory.activeRegion = memory->bios7; if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) {
cpu->memory.activeMask = DS7_SIZE_BIOS - 1; cpu->memory.activeRegion = memory->ram;
break; cpu->memory.activeMask = DS_SIZE_RAM - 1;
default:
mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address);
return; return;
} }
break;
case DS7_REGION_BIOS:
if (memory->bios7) {
cpu->memory.activeRegion = memory->bios9;
cpu->memory.activeMask = DS9_SIZE_BIOS - 1;
} else {
cpu->memory.activeRegion = _deadbeef;
cpu->memory.activeMask = 0;
}
return;
default:
break;
}
cpu->memory.activeRegion = _deadbeef;
cpu->memory.activeMask = 0;
mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address);
return;
} }
uint32_t DS7Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { uint32_t DS7Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
@ -178,6 +196,11 @@ uint32_t DS7Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
int wait = 0; int wait = 0;
switch (address >> DS_BASE_OFFSET) { switch (address >> DS_BASE_OFFSET) {
case DS_REGION_RAM:
if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) {
LOAD_32(value, address & (DS_SIZE_RAM - 1), memory->ram);
}
break;
default: default:
break; break;
} }
@ -321,7 +344,7 @@ uint32_t DS7LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
uint32_t DS7StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) { uint32_t DS7StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
struct DS* ds = (struct ds*) cpu->master; struct DS* ds = (struct DS*) cpu->master;
struct DSMemory* memory = &ds->memory; struct DSMemory* memory = &ds->memory;
uint32_t value; uint32_t value;
int wait = 0; int wait = 0;
@ -368,8 +391,15 @@ static void DS9SetActiveRegion(struct ARMCore* cpu, uint32_t address) {
int newRegion = address >> DS_BASE_OFFSET; int newRegion = address >> DS_BASE_OFFSET;
memory->activeRegion7 = newRegion; memory->activeRegion9 = newRegion;
switch (newRegion) { switch (newRegion) {
case DS_REGION_RAM:
if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) {
cpu->memory.activeRegion = memory->ram;
cpu->memory.activeMask = DS_SIZE_RAM - 1;
return;
}
break;
case DS9_REGION_BIOS: case DS9_REGION_BIOS:
// TODO: Mask properly // TODO: Mask properly
if (memory->bios9) { if (memory->bios9) {
@ -379,11 +409,14 @@ static void DS9SetActiveRegion(struct ARMCore* cpu, uint32_t address) {
cpu->memory.activeRegion = _deadbeef; cpu->memory.activeRegion = _deadbeef;
cpu->memory.activeMask = 0; cpu->memory.activeMask = 0;
} }
break; return;
default: default:
break;
}
cpu->memory.activeRegion = _deadbeef;
cpu->memory.activeMask = 0;
mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address); mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address);
return; return;
}
} }
uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
@ -393,6 +426,11 @@ uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
int wait = 0; int wait = 0;
switch (address >> DS_BASE_OFFSET) { switch (address >> DS_BASE_OFFSET) {
case DS_REGION_RAM:
if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) {
LOAD_32(value, address & (DS_SIZE_RAM - 1), memory->ram);
}
break;
default: default:
break; break;
} }
@ -536,7 +574,7 @@ uint32_t DS9LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
uint32_t DS9StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) { uint32_t DS9StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
struct DS* ds = (struct ds*) cpu->master; struct DS* ds = (struct DS*) cpu->master;
struct DSMemory* memory = &ds->memory; struct DSMemory* memory = &ds->memory;
uint32_t value; uint32_t value;
int wait = 0; int wait = 0;