Permalink
Browse files

GBA Memory: Matrix Memory support

  • Loading branch information...
endrift committed Jan 14, 2018
1 parent cee6569 commit 38e3dbc0fcec4356fff4212dee2c905d494f6c69
Showing with 136 additions and 9 deletions.
  1. +1 −0 CHANGES
  2. +28 −0 include/mgba/internal/gba/matrix.h
  3. +2 −0 include/mgba/internal/gba/memory.h
  4. +21 −9 src/gba/gba.c
  5. +75 −0 src/gba/matrix.c
  6. +9 −0 src/gba/memory.c
View
@@ -55,6 +55,7 @@ Misc:
- GBA Cheats: Allow multiple ROM patches in the same slot
- GB: Skip BIOS option now works
- Libretro: Add frameskip option
+ - GBA Memory: 64 MiB GBA Video cartridge support
0.6.1: (2017-10-01)
Bugfixes:
@@ -0,0 +1,28 @@
+/* Copyright (c) 2013-2018 Jeffrey Pfau
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+#ifndef GBA_MATRIX_H
+#define GBA_MATRIX_H
+
+#include <mgba-util/common.h>
+
+CXX_GUARD_START
+
+struct GBAMatrix {
+ uint32_t cmd;
+ uint32_t paddr;
+ uint32_t vaddr;
+ uint32_t size;
+};
+
+struct GBA;
+struct GBAMemory;
+void GBAMatrixReset(struct GBA*);
+void GBAMatrixWrite(struct GBA*, uint32_t address, uint32_t value);
+void GBAMatrixWrite16(struct GBA*, uint32_t address, uint16_t value);
+
+CXX_GUARD_END
+
+#endif
@@ -17,6 +17,7 @@ CXX_GUARD_START
#include <mgba/internal/gba/hardware.h>
#include <mgba/internal/gba/savedata.h>
#include <mgba/internal/gba/vfame.h>
+#include <mgba/internal/gba/matrix.h>
enum GBAMemoryRegion {
REGION_BIOS = 0x0,
@@ -106,6 +107,7 @@ struct GBAMemory {
struct GBACartridgeHardware hw;
struct GBASavedata savedata;
struct GBAVFameCart vfame;
+ struct GBAMatrix matrix;
size_t romSize;
uint32_t romMask;
uint16_t romID;
View
@@ -125,7 +125,9 @@ void GBAUnloadROM(struct GBA* gba) {
if (gba->romVf) {
#ifndef FIXED_ROM_BUFFER
- gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->pristineRomSize);
+ if (gba->isPristine) {
+ gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->pristineRomSize);
+ }
#endif
gba->romVf->close(gba->romVf);
gba->romVf = NULL;
@@ -207,6 +209,9 @@ void GBAReset(struct ARMCore* cpu) {
gba->debug = false;
memset(gba->debugString, 0, sizeof(gba->debugString));
+ if (gba->pristineRomSize > SIZE_CART0) {
+ GBAMatrixReset(gba);
+ }
if (!gba->romVf && gba->memory.rom) {
GBASkipBIOS(gba);
@@ -355,23 +360,30 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) {
gba->pristineRomSize = vf->size(vf);
vf->seek(vf, 0, SEEK_SET);
if (gba->pristineRomSize > SIZE_CART0) {
- gba->pristineRomSize = SIZE_CART0;
- }
- gba->isPristine = true;
+ gba->isPristine = false;
+ gba->memory.romSize = 0x01000000;
#ifdef FIXED_ROM_BUFFER
- if (gba->pristineRomSize <= romBufferSize) {
gba->memory.rom = romBuffer;
- vf->read(vf, romBuffer, gba->pristineRomSize);
- }
#else
- gba->memory.rom = vf->map(vf, gba->pristineRomSize, MAP_READ);
+ gba->memory.rom = anonymousMemoryMap(SIZE_CART0);
#endif
+ } else {
+ gba->isPristine = true;
+#ifdef FIXED_ROM_BUFFER
+ if (gba->pristineRomSize <= romBufferSize) {
+ gba->memory.rom = romBuffer;
+ vf->read(vf, romBuffer, gba->pristineRomSize);
+ }
+#else
+ gba->memory.rom = vf->map(vf, gba->pristineRomSize, MAP_READ);
+#endif
+ gba->memory.romSize = gba->pristineRomSize;
+ }
if (!gba->memory.rom) {
mLOG(GBA, WARN, "Couldn't map ROM");
return false;
}
gba->yankedRomSize = 0;
- gba->memory.romSize = gba->pristineRomSize;
gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
gba->memory.mirroring = false;
gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize);
View
@@ -0,0 +1,75 @@
+/* Copyright (c) 2013-2018 Jeffrey Pfau
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * 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 <mgba/internal/gba/matrix.h>
+
+#include <mgba/internal/arm/macros.h>
+#include <mgba/internal/gba/gba.h>
+#include <mgba/internal/gba/memory.h>
+#include <mgba-util/vfs.h>
+
+static void _remapMatrix(struct GBA* gba) {
+ gba->romVf->seek(gba->romVf, gba->memory.matrix.paddr, SEEK_SET);
+ gba->romVf->read(gba->romVf, &gba->memory.rom[gba->memory.matrix.vaddr >> 2], gba->memory.matrix.size);
+}
+
+void GBAMatrixReset(struct GBA* gba) {
+ gba->memory.matrix.paddr = 0x200;
+ gba->memory.matrix.size = 0x1000;
+
+ gba->memory.matrix.vaddr = 0;
+ _remapMatrix(gba);
+ gba->memory.matrix.vaddr = 0x1000;
+ _remapMatrix(gba);
+
+ gba->memory.matrix.paddr = 0;
+ gba->memory.matrix.vaddr = 0;
+ gba->memory.matrix.size = 0x100;
+ _remapMatrix(gba);
+}
+
+void GBAMatrixWrite(struct GBA* gba, uint32_t address, uint32_t value) {
+ switch (address) {
+ case 0x0:
+ gba->memory.matrix.cmd = value;
+ switch (value) {
+ case 0x01:
+ case 0x11:
+ _remapMatrix(gba);
+ break;
+ default:
+ mLOG(GBA_MEM, STUB, "Unknown Matrix command: %08X", value);
+ break;
+ }
+ return;
+ case 0x4:
+ gba->memory.matrix.paddr = value & 0x03FFFFFF;
+ return;
+ case 0x8:
+ gba->memory.matrix.vaddr = value & 0x007FFFFF;
+ return;
+ case 0xC:
+ gba->memory.matrix.size = value << 9;
+ return;
+ }
+ mLOG(GBA_MEM, STUB, "Unknown Matrix write: %08X:%04X", address, value);
+}
+
+void GBAMatrixWrite16(struct GBA* gba, uint32_t address, uint16_t value) {
+ switch (address) {
+ case 0x0:
+ GBAMatrixWrite(gba, address, value | (gba->memory.matrix.cmd & 0xFFFF0000));
+ break;
+ case 0x4:
+ GBAMatrixWrite(gba, address, value | (gba->memory.matrix.paddr & 0xFFFF0000));
+ break;
+ case 0x8:
+ GBAMatrixWrite(gba, address, value | (gba->memory.matrix.vaddr & 0xFFFF0000));
+ break;
+ case 0xC:
+ GBAMatrixWrite(gba, address, value | (gba->memory.matrix.size & 0xFFFF0000));
+ break;
+ }
+}
View
@@ -137,6 +137,7 @@ void GBAMemoryReset(struct GBA* gba) {
}
GBADMAReset(gba);
+ memset(&gba->memory.matrix, 0, sizeof(gba->memory.matrix));
}
static void _analyzeForIdleLoop(struct GBA* gba, struct ARMCore* cpu, uint32_t address) {
@@ -748,6 +749,10 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
#define STORE_CART \
wait += waitstatesRegion[address >> BASE_OFFSET]; \
+ if (memory->matrix.size && (address & 0x01FFFF00) == 0x00800100) { \
+ GBAMatrixWrite(gba, address & 0x3C, value); \
+ break; \
+ } \
mLOG(GBA_MEM, STUB, "Unimplemented memory Store32: 0x%08X", address);
#define STORE_SRAM \
@@ -867,6 +872,10 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
GBAHardwareGPIOWrite(&memory->hw, reg, value);
break;
}
+ if (memory->matrix.size && (address & 0x01FFFF00) == 0x00800100) {
+ GBAMatrixWrite16(gba, address & 0x3C, value);
+ break;
+ }
// Fall through
case REGION_CART0_EX:
if ((address & 0x00FFFFFF) >= AGB_PRINT_BASE) {

0 comments on commit 38e3dbc

Please sign in to comment.