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);