1 /* Copyright (c) 2013-2018 Jeffrey Pfau
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include <mgba/internal/gba/matrix.h>
7 
8 #include <mgba/internal/arm/macros.h>
9 #include <mgba/internal/gba/gba.h>
10 #include <mgba/internal/gba/memory.h>
11 #include <mgba-util/vfs.h>
12 
_remapMatrix(struct GBA * gba)13 static void _remapMatrix(struct GBA* gba) {
14 	gba->romVf->seek(gba->romVf, gba->memory.matrix.paddr, SEEK_SET);
15 	gba->romVf->read(gba->romVf, &gba->memory.rom[gba->memory.matrix.vaddr >> 2], gba->memory.matrix.size);
16 }
17 
GBAMatrixReset(struct GBA * gba)18 void GBAMatrixReset(struct GBA* gba) {
19 	gba->memory.matrix.paddr = 0x200;
20 	gba->memory.matrix.size = 0x1000;
21 
22 	gba->memory.matrix.vaddr = 0;
23 	_remapMatrix(gba);
24 	gba->memory.matrix.vaddr = 0x1000;
25 	_remapMatrix(gba);
26 
27 	gba->memory.matrix.paddr = 0;
28 	gba->memory.matrix.vaddr = 0;
29 	gba->memory.matrix.size = 0x100;
30 	_remapMatrix(gba);
31 }
32 
GBAMatrixWrite(struct GBA * gba,uint32_t address,uint32_t value)33 void GBAMatrixWrite(struct GBA* gba, uint32_t address, uint32_t value) {
34 	switch (address) {
35 	case 0x0:
36 		gba->memory.matrix.cmd = value;
37 		switch (value) {
38 		case 0x01:
39 		case 0x11:
40 			_remapMatrix(gba);
41 			break;
42 		default:
43 			mLOG(GBA_MEM, STUB, "Unknown Matrix command: %08X", value);
44 			break;
45 		}
46 		return;
47 	case 0x4:
48 		gba->memory.matrix.paddr = value & 0x03FFFFFF;
49 		return;
50 	case 0x8:
51 		gba->memory.matrix.vaddr = value & 0x007FFFFF;
52 		return;
53 	case 0xC:
54 		gba->memory.matrix.size = value << 9;
55 		return;
56 	}
57 	mLOG(GBA_MEM, STUB, "Unknown Matrix write: %08X:%04X", address, value);
58 }
59 
GBAMatrixWrite16(struct GBA * gba,uint32_t address,uint16_t value)60 void GBAMatrixWrite16(struct GBA* gba, uint32_t address, uint16_t value) {
61 	switch (address) {
62 	case 0x0:
63 		GBAMatrixWrite(gba, address, value | (gba->memory.matrix.cmd & 0xFFFF0000));
64 		break;
65 	case 0x4:
66 		GBAMatrixWrite(gba, address, value | (gba->memory.matrix.paddr & 0xFFFF0000));
67 		break;
68 	case 0x8:
69 		GBAMatrixWrite(gba, address, value | (gba->memory.matrix.vaddr & 0xFFFF0000));
70 		break;
71 	case 0xC:
72 		GBAMatrixWrite(gba, address, value | (gba->memory.matrix.size & 0xFFFF0000));
73 		break;
74 	}
75 }
76