Skip to content

Commit

Permalink
GBA Memory: Matrix Memory support
Browse files Browse the repository at this point in the history
  • Loading branch information
endrift committed Jan 14, 2018
1 parent cee6569 commit 38e3dbc
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
28 changes: 28 additions & 0 deletions include/mgba/internal/gba/matrix.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions include/mgba/internal/gba/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
30 changes: 21 additions & 9 deletions src/gba/gba.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
75 changes: 75 additions & 0 deletions src/gba/matrix.c
Original file line number Diff line number Diff line change
@@ -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;
}
}
9 changes: 9 additions & 0 deletions src/gba/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 38e3dbc

Please sign in to comment.