all repos — mgba @ 2006f27d6da1fba91f4ec2e34a9fa736c3af07f6

mGBA Game Boy Advance Emulator

DS: Basic memory support for RAM
Jeffrey Pfau jeffrey@endrift.com
Wed, 01 Jun 2016 20:21:00 -0700
commit

2006f27d6da1fba91f4ec2e34a9fa736c3af07f6

parent

e93154fb417d77b4ffb4f275a0623e6bff3526b1

2 files changed, 87 insertions(+), 13 deletions(-)

jump to
M src/ds/ds.csrc/ds/ds.c

@@ -129,6 +129,27 @@ ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);

cpu->gprs[ARM_SP] = DS7_SP_BASE_SVC; ARMSetPrivilegeMode(cpu, MODE_SYSTEM); 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) {

@@ -140,7 +161,23 @@ ARMSetPrivilegeMode(cpu, MODE_SYSTEM);

cpu->gprs[ARM_SP] = DS9_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->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) {

@@ -189,7 +226,6 @@

bool DSLoadROM(struct DS* ds, struct VFile* vf) { DSUnloadROM(ds); ds->romVf = vf; - // TODO: Checksum? // TODO: error check return true; }
M src/ds/memory.csrc/ds/memory.c

@@ -5,8 +5,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this

* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "memory.h" +#include "arm/macros.h" + #include "ds/ds.h" #include "util/math.h" +#include "util/memory.h" mLOG_DEFINE_CATEGORY(DS_MEM, "DS Memory");

@@ -161,14 +164,29 @@ int newRegion = address >> DS_BASE_OFFSET;

memory->activeRegion7 = 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 DS7_REGION_BIOS: - cpu->memory.activeRegion = memory->bios7; - cpu->memory.activeMask = DS7_SIZE_BIOS - 1; + 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; - default: - mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address); - return; } + 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) {

@@ -178,6 +196,11 @@ uint32_t value = 0;

int wait = 0; 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: break; }

@@ -321,7 +344,7 @@ }

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; uint32_t value; int wait = 0;

@@ -368,8 +391,15 @@ struct DSMemory* memory = &ds->memory;

int newRegion = address >> DS_BASE_OFFSET; - memory->activeRegion7 = newRegion; + memory->activeRegion9 = 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: // TODO: Mask properly if (memory->bios9) {

@@ -379,11 +409,14 @@ } else {

cpu->memory.activeRegion = _deadbeef; cpu->memory.activeMask = 0; } - break; - default: - mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address); return; + default: + break; } + cpu->memory.activeRegion = _deadbeef; + cpu->memory.activeMask = 0; + mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address); + return; } uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {

@@ -393,6 +426,11 @@ uint32_t value = 0;

int wait = 0; 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: break; }

@@ -536,7 +574,7 @@ }

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; uint32_t value; int wait = 0;