all repos — mgba @ b104a5cd1cba1dbe44e7e60b3f041772fda96d0c

mGBA Game Boy Advance Emulator

src/gb/memory.c (view raw)

  1/* Copyright (c) 2013-2016 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 "memory.h"
  7
  8#include "gb/gb.h"
  9#include "gb/io.h"
 10
 11#include "util/memory.h"
 12
 13static void GBSetActiveRegion(struct LR35902Core* cpu, uint16_t address) {
 14	// TODO
 15}
 16
 17void GBMemoryInit(struct GB* gb) {
 18	struct LR35902Core* cpu = gb->cpu;
 19	cpu->memory.load16 = GBLoad16;
 20	cpu->memory.load8 = GBLoad8;
 21	cpu->memory.store16 = GBStore16;
 22	cpu->memory.store8 = GBStore8;
 23	cpu->memory.setActiveRegion = GBSetActiveRegion;
 24
 25	gb->memory.wram = 0;
 26	gb->memory.wramBank = 0;
 27	gb->memory.rom = 0;
 28	gb->memory.romBank = 0;
 29	gb->memory.romSize = 0;
 30
 31	memset(gb->memory.hram, 0, sizeof(gb->memory.hram));
 32
 33	GBIOInit(gb);
 34}
 35
 36void GBMemoryDeinit(struct GB* gb) {
 37	mappedMemoryFree(gb->memory.wram, GB_SIZE_WORKING_RAM);
 38	if (gb->memory.rom) {
 39		mappedMemoryFree(gb->memory.rom, gb->memory.romSize);
 40	}
 41}
 42
 43void GBMemoryReset(struct GB* gb) {
 44	if (gb->memory.wram) {
 45		mappedMemoryFree(gb->memory.wram, GB_SIZE_WORKING_RAM);
 46	}
 47	gb->memory.wram = anonymousMemoryMap(GB_SIZE_WORKING_RAM);
 48	gb->memory.wramBank = &gb->memory.wram[GB_SIZE_WORKING_RAM_BANK0];
 49	gb->memory.romBank = &gb->memory.rom[GB_BASE_CART_BANK0];
 50
 51	if (!gb->memory.wram) {
 52		GBMemoryDeinit(gb);
 53	}
 54}
 55
 56uint16_t GBLoad16(struct LR35902Core* cpu, uint16_t address) {
 57	// TODO
 58}
 59
 60uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address) {
 61	struct GB* gb = (struct GB*) cpu->master;
 62	struct GBMemory* memory = &gb->memory;
 63	switch (address >> 12) {
 64	case GB_REGION_CART_BANK0:
 65	case GB_REGION_CART_BANK0 + 1:
 66	case GB_REGION_CART_BANK0 + 2:
 67	case GB_REGION_CART_BANK0 + 3:
 68		return memory->rom[address & (GB_SIZE_CART_BANK0 - 1)];
 69	case GB_REGION_CART_BANK1:
 70	case GB_REGION_CART_BANK1 + 1:
 71	case GB_REGION_CART_BANK1 + 2:
 72	case GB_REGION_CART_BANK1 + 3:
 73		return memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)];
 74	case GB_REGION_VRAM:
 75	case GB_REGION_VRAM + 1:
 76		// TODO
 77		return 0;
 78	case GB_REGION_EXTERNAL_RAM:
 79	case GB_REGION_EXTERNAL_RAM + 1:
 80		// TODO
 81		return 0;
 82	case GB_REGION_WORKING_RAM_BANK0:
 83	case GB_REGION_WORKING_RAM_BANK0 + 2:
 84		return memory->wram[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)];
 85	case GB_REGION_WORKING_RAM_BANK1:
 86		return memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)];
 87	default:
 88		if (address < GB_BASE_OAM) {
 89			return memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)];
 90		}
 91		if (address < GB_BASE_IO) {
 92			// TODO
 93			return 0;
 94		}
 95		if (address < GB_BASE_HRAM) {
 96			return GBIORead(gb, address & (GB_SIZE_IO - 1));
 97		}
 98		if (address < GB_BASE_IE) {
 99			return memory->hram[address & GB_SIZE_HRAM];
100		}
101		return GBIORead(gb, REG_IE);
102	}
103}
104
105void GBStore16(struct LR35902Core* cpu, uint16_t address, int16_t value) {
106	// TODO
107}
108
109void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
110	struct GB* gb = (struct GB*) cpu->master;
111	struct GBMemory* memory = &gb->memory;
112	switch (address >> 12) {
113	case GB_REGION_CART_BANK0:
114	case GB_REGION_CART_BANK0 + 1:
115	case GB_REGION_CART_BANK0 + 2:
116	case GB_REGION_CART_BANK0 + 3:
117		// TODO
118		return;
119	case GB_REGION_CART_BANK1:
120	case GB_REGION_CART_BANK1 + 1:
121	case GB_REGION_CART_BANK1 + 2:
122	case GB_REGION_CART_BANK1 + 3:
123		// TODO
124		return;
125	case GB_REGION_VRAM:
126	case GB_REGION_VRAM + 1:
127		// TODO
128		return;
129	case GB_REGION_EXTERNAL_RAM:
130	case GB_REGION_EXTERNAL_RAM + 1:
131		// TODO
132		return;
133	case GB_REGION_WORKING_RAM_BANK0:
134	case GB_REGION_WORKING_RAM_BANK0 + 2:
135		memory->wram[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
136		return;
137	case GB_REGION_WORKING_RAM_BANK1:
138		memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
139		return;
140	default:
141		if (address < GB_BASE_OAM) {
142			memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
143		} else if (address < GB_BASE_IO) {
144			// TODO
145		} else if (address < GB_BASE_HRAM) {
146			GBIOWrite(gb, address & (GB_SIZE_IO - 1), value);
147		} else if (address < GB_BASE_IE) {
148			memory->hram[address & GB_SIZE_HRAM] = value;
149		} else {
150			GBIOWrite(gb, REG_IE, value);
151		}
152	}
153}
154
155uint16_t GBView16(struct LR35902Core* cpu, uint16_t address);
156uint8_t GBView8(struct LR35902Core* cpu, uint16_t address);
157
158void GBPatch16(struct LR35902Core* cpu, uint16_t address, int16_t value, int16_t* old);
159void GBPatch8(struct LR35902Core* cpu, uint16_t address, int8_t value, int8_t* old);