From 2006f27d6da1fba91f4ec2e34a9fa736c3af07f6 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 1 Jun 2016 20:21:00 -0700 Subject: [PATCH] DS: Basic memory support for RAM --- src/ds/ds.c | 40 +++++++++++++++++++++++++++++++-- src/ds/memory.c | 60 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 13 deletions(-) diff --git a/src/ds/ds.c b/src/ds/ds.c index a4a8184be..bc6eb6f41 100644 --- a/src/ds/ds.c +++ b/src/ds/ds.c @@ -129,6 +129,27 @@ void DS7Reset(struct ARMCore* cpu) { 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 @@ void DS9Reset(struct ARMCore* cpu) { 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 @@ void DSDetachDebugger(struct DS* ds) { bool DSLoadROM(struct DS* ds, struct VFile* vf) { DSUnloadROM(ds); ds->romVf = vf; - // TODO: Checksum? // TODO: error check return true; } diff --git a/src/ds/memory.c b/src/ds/memory.c index c6c8c57db..36886f23b 100644 --- a/src/ds/memory.c +++ b/src/ds/memory.c @@ -5,8 +5,11 @@ * 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 @@ static void DS7SetActiveRegion(struct ARMCore* cpu, uint32_t address) { memory->activeRegion7 = newRegion; switch (newRegion) { - case DS7_REGION_BIOS: - cpu->memory.activeRegion = memory->bios7; - cpu->memory.activeMask = DS7_SIZE_BIOS - 1; + 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; - default: - mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address); + 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) { @@ -178,6 +196,11 @@ uint32_t DS7Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { 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 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) { - 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 @@ static void DS9SetActiveRegion(struct ARMCore* cpu, uint32_t address) { 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 @@ static void DS9SetActiveRegion(struct ARMCore* cpu, uint32_t address) { 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 DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { 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 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) { - 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;