src/gb/mbc.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 "mbc.h"
7
8#include "gb/gb.h"
9#include "gb/memory.h"
10#include "util/vfs.h"
11
12mLOG_DEFINE_CATEGORY(GB_MBC, "GB MBC");
13
14static void _GBMBCNone(struct GB* gb, uint16_t address, uint8_t value) {
15 UNUSED(gb);
16 UNUSED(address);
17 UNUSED(value);
18
19 mLOG(GB_MBC, GAME_ERROR, "Wrote to invalid MBC");
20}
21
22static void _GBMBC1(struct GB*, uint16_t address, uint8_t value);
23static void _GBMBC2(struct GB*, uint16_t address, uint8_t value);
24static void _GBMBC3(struct GB*, uint16_t address, uint8_t value);
25static void _GBMBC5(struct GB*, uint16_t address, uint8_t value);
26static void _GBMBC6(struct GB*, uint16_t address, uint8_t value);
27static void _GBMBC7(struct GB*, uint16_t address, uint8_t value);
28static void _GBHuC3(struct GB*, uint16_t address, uint8_t value);
29
30void GBMBCSwitchBank(struct GBMemory* memory, int bank) {
31 size_t bankStart = bank * GB_SIZE_CART_BANK0;
32 if (bankStart + GB_SIZE_CART_BANK0 > memory->romSize) {
33 mLOG(GB_MBC, GAME_ERROR, "Attempting to switch to an invalid ROM bank: %0X", bank);
34 bankStart &= (memory->romSize - 1);
35 bank = bankStart / GB_SIZE_CART_BANK0;
36 }
37 memory->romBank = &memory->rom[bankStart];
38 memory->currentBank = bank;
39}
40
41void GBMBCSwitchSramBank(struct GB* gb, int bank) {
42 size_t bankStart = bank * GB_SIZE_EXTERNAL_RAM;
43 GBResizeSram(gb, (bank + 1) * GB_SIZE_EXTERNAL_RAM);
44 gb->memory.sramBank = &gb->memory.sram[bankStart];
45 gb->memory.sramCurrentBank = bank;
46}
47
48void GBMBCInit(struct GB* gb) {
49 const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
50 switch (cart->ramSize) {
51 case 0:
52 gb->sramSize = 0;
53 break;
54 case 1:
55 gb->sramSize = 0x800;
56 break;
57 default:
58 case 2:
59 gb->sramSize = 0x2000;
60 break;
61 case 3:
62 gb->sramSize = 0x8000;
63 break;
64 }
65
66 if (gb->memory.mbcType == GB_MBC_AUTODETECT) {
67 const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
68 switch (cart->type) {
69 case 0:
70 case 8:
71 case 9:
72 gb->memory.mbcType = GB_MBC_NONE;
73 break;
74 case 1:
75 case 2:
76 case 3:
77 gb->memory.mbcType = GB_MBC1;
78 break;
79 case 5:
80 case 6:
81 gb->memory.mbcType = GB_MBC2;
82 break;
83 case 0x0F:
84 case 0x10:
85 gb->memory.mbcType = GB_MBC3_RTC;
86 break;
87 case 0x11:
88 case 0x12:
89 case 0x13:
90 gb->memory.mbcType = GB_MBC3;
91 break;
92 default:
93 mLOG(GB_MBC, WARN, "Unknown MBC type: %02X", cart->type);
94 // Fall through
95 case 0x19:
96 case 0x1A:
97 case 0x1B:
98 gb->memory.mbcType = GB_MBC5;
99 break;
100 case 0x1C:
101 case 0x1D:
102 case 0x1E:
103 gb->memory.mbcType = GB_MBC5_RUMBLE;
104 break;
105 case 0x20:
106 gb->memory.mbcType = GB_MBC6;
107 break;
108 case 0x22:
109 gb->memory.mbcType = GB_MBC7;
110 break;
111 case 0xFE:
112 gb->memory.mbcType = GB_HuC3;
113 break;
114 }
115 }
116 switch (gb->memory.mbcType) {
117 case GB_MBC_NONE:
118 gb->memory.mbc = _GBMBCNone;
119 break;
120 case GB_MBC1:
121 gb->memory.mbc = _GBMBC1;
122 break;
123 case GB_MBC2:
124 gb->memory.mbc = _GBMBC2;
125 gb->sramSize = 0x200;
126 break;
127 case GB_MBC3:
128 gb->memory.mbc = _GBMBC3;
129 break;
130 default:
131 mLOG(GB_MBC, WARN, "Unknown MBC type: %02X", cart->type);
132 // Fall through
133 case GB_MBC5:
134 gb->memory.mbc = _GBMBC5;
135 break;
136 case GB_MBC6:
137 mLOG(GB_MBC, WARN, "unimplemented MBC: MBC6");
138 gb->memory.mbc = _GBMBC6;
139 break;
140 case GB_MBC7:
141 gb->memory.mbc = _GBMBC7;
142 gb->sramSize = GB_SIZE_EXTERNAL_RAM;
143 break;
144 case GB_MMM01:
145 mLOG(GB_MBC, WARN, "unimplemented MBC: MMM01");
146 gb->memory.mbc = _GBMBC1;
147 break;
148 case GB_HuC1:
149 mLOG(GB_MBC, WARN, "unimplemented MBC: HuC-1");
150 gb->memory.mbc = _GBMBC1;
151 break;
152 case GB_HuC3:
153 gb->memory.mbc = _GBHuC3;
154 break;
155 case GB_MBC3_RTC:
156 memset(gb->memory.rtcRegs, 0, sizeof(gb->memory.rtcRegs));
157 gb->memory.mbc = _GBMBC3;
158 break;
159 case GB_MBC5_RUMBLE:
160 gb->memory.mbc = _GBMBC5;
161 break;
162 }
163
164 GBResizeSram(gb, gb->sramSize);
165
166 if (gb->memory.mbcType == GB_MBC3_RTC) {
167 GBMBCRTCRead(gb);
168 }
169}
170
171static void _latchRtc(struct mRTCSource* rtc, uint8_t* rtcRegs, time_t* rtcLastLatch) {
172 time_t t;
173 if (rtc) {
174 if (rtc->sample) {
175 rtc->sample(rtc);
176 }
177 t = rtc->unixTime(rtc);
178 } else {
179 t = time(0);
180 }
181 time_t currentLatch = t;
182 t -= *rtcLastLatch;
183 *rtcLastLatch = currentLatch;
184
185 int64_t diff;
186 diff = rtcRegs[0] + t % 60;
187 if (diff < 0) {
188 diff += 60;
189 t -= 60;
190 }
191 rtcRegs[0] = diff % 60;
192 t /= 60;
193 t += diff / 60;
194
195 diff = rtcRegs[1] + t % 60;
196 if (diff < 0) {
197 diff += 60;
198 t -= 60;
199 }
200 rtcRegs[1] = diff % 60;
201 t /= 60;
202 t += diff / 60;
203
204 diff = rtcRegs[2] + t % 24;
205 if (diff < 0) {
206 diff += 24;
207 t -= 24;
208 }
209 rtcRegs[2] = diff % 24;
210 t /= 24;
211 t += diff / 24;
212
213 diff = rtcRegs[3] + ((rtcRegs[4] & 1) << 8) + (t & 0x1FF);
214 rtcRegs[3] = diff;
215 rtcRegs[4] &= 0xFE;
216 rtcRegs[4] |= (diff >> 8) & 1;
217 if (diff & 0x200) {
218 rtcRegs[4] |= 0x80;
219 }
220}
221
222void _GBMBC1(struct GB* gb, uint16_t address, uint8_t value) {
223 struct GBMemory* memory = &gb->memory;
224 int bank = value & 0x1F;
225 switch (address >> 13) {
226 case 0x0:
227 switch (value) {
228 case 0:
229 memory->sramAccess = false;
230 break;
231 case 0xA:
232 memory->sramAccess = true;
233 GBMBCSwitchSramBank(gb, memory->sramCurrentBank);
234 break;
235 default:
236 // TODO
237 mLOG(GB_MBC, STUB, "MBC1 unknown value %02X", value);
238 break;
239 }
240 break;
241 case 0x1:
242 if (!bank) {
243 ++bank;
244 }
245 GBMBCSwitchBank(memory, bank | (memory->currentBank & 0x60));
246 break;
247 case 0x2:
248 bank &= 3;
249 if (!memory->mbcState.mbc1.mode) {
250 GBMBCSwitchBank(memory, (bank << 5) | (memory->currentBank & 0x1F));
251 } else {
252 GBMBCSwitchSramBank(gb, bank);
253 }
254 break;
255 case 0x3:
256 memory->mbcState.mbc1.mode = value & 1;
257 if (memory->mbcState.mbc1.mode) {
258 GBMBCSwitchBank(memory, memory->currentBank & 0x1F);
259 } else {
260 GBMBCSwitchSramBank(gb, 0);
261 }
262 break;
263 default:
264 // TODO
265 mLOG(GB_MBC, STUB, "MBC1 unknown address: %04X:%02X", address, value);
266 break;
267 }
268}
269
270void _GBMBC2(struct GB* gb, uint16_t address, uint8_t value) {
271 struct GBMemory* memory = &gb->memory;
272 int bank = value & 0xF;
273 switch (address >> 13) {
274 case 0x0:
275 switch (value) {
276 case 0:
277 memory->sramAccess = false;
278 break;
279 case 0xA:
280 memory->sramAccess = true;
281 GBMBCSwitchSramBank(gb, memory->sramCurrentBank);
282 break;
283 default:
284 // TODO
285 mLOG(GB_MBC, STUB, "MBC1 unknown value %02X", value);
286 break;
287 }
288 break;
289 case 0x1:
290 if (!bank) {
291 ++bank;
292 }
293 GBMBCSwitchBank(memory, bank);
294 break;
295 default:
296 // TODO
297 mLOG(GB_MBC, STUB, "MBC2 unknown address: %04X:%02X", address, value);
298 break;
299 }}
300
301void _GBMBC3(struct GB* gb, uint16_t address, uint8_t value) {
302 struct GBMemory* memory = &gb->memory;
303 int bank = value & 0x7F;
304 switch (address >> 13) {
305 case 0x0:
306 switch (value) {
307 case 0:
308 memory->sramAccess = false;
309 break;
310 case 0xA:
311 memory->sramAccess = true;
312 GBMBCSwitchSramBank(gb, memory->sramCurrentBank);
313 break;
314 default:
315 // TODO
316 mLOG(GB_MBC, STUB, "MBC3 unknown value %02X", value);
317 break;
318 }
319 break;
320 case 0x1:
321 if (!bank) {
322 ++bank;
323 }
324 GBMBCSwitchBank(memory, bank);
325 break;
326 case 0x2:
327 if (value < 4) {
328 GBMBCSwitchSramBank(gb, value);
329 memory->rtcAccess = false;
330 } else if (value >= 8 && value <= 0xC) {
331 memory->activeRtcReg = value - 8;
332 memory->rtcAccess = true;
333 }
334 break;
335 case 0x3:
336 if (memory->rtcLatched && value == 0) {
337 memory->rtcLatched = false;
338 } else if (!memory->rtcLatched && value == 1) {
339 _latchRtc(gb->memory.rtc, gb->memory.rtcRegs, &gb->memory.rtcLastLatch);
340 memory->rtcLatched = true;
341 }
342 break;
343 }
344}
345
346void _GBMBC5(struct GB* gb, uint16_t address, uint8_t value) {
347 struct GBMemory* memory = &gb->memory;
348 int bank;
349 switch (address >> 12) {
350 case 0x0:
351 case 0x1:
352 switch (value) {
353 case 0:
354 memory->sramAccess = false;
355 break;
356 case 0xA:
357 memory->sramAccess = true;
358 GBMBCSwitchSramBank(gb, memory->sramCurrentBank);
359 break;
360 default:
361 // TODO
362 mLOG(GB_MBC, STUB, "MBC5 unknown value %02X", value);
363 break;
364 }
365 break;
366 case 0x2:
367 bank = (memory->currentBank & 0x100) | value;
368 GBMBCSwitchBank(memory, bank);
369 break;
370 case 0x3:
371 bank = (memory->currentBank & 0xFF) | ((value & 1) << 8);
372 GBMBCSwitchBank(memory, bank);
373 break;
374 case 0x4:
375 case 0x5:
376 if (memory->mbcType == GB_MBC5_RUMBLE && memory->rumble) {
377 memory->rumble->setRumble(memory->rumble, (value >> 3) & 1);
378 value &= ~8;
379 }
380 GBMBCSwitchSramBank(gb, value & 0xF);
381 break;
382 default:
383 // TODO
384 mLOG(GB_MBC, STUB, "MBC5 unknown address: %04X:%02X", address, value);
385 break;
386 }
387}
388
389void _GBMBC6(struct GB* gb, uint16_t address, uint8_t value) {
390 // TODO
391 mLOG(GB_MBC, STUB, "MBC6 unimplemented");
392 UNUSED(gb);
393 UNUSED(address);
394 UNUSED(value);
395}
396
397void _GBMBC7(struct GB* gb, uint16_t address, uint8_t value) {
398 struct GBMemory* memory = &gb->memory;
399 int bank = value & 0x7F;
400 switch (address >> 13) {
401 case 0x1:
402 GBMBCSwitchBank(memory, bank);
403 break;
404 case 0x2:
405 if (value < 0x10) {
406 GBMBCSwitchSramBank(gb, value);
407 }
408 break;
409 default:
410 // TODO
411 mLOG(GB_MBC, STUB, "MBC7 unknown address: %04X:%02X", address, value);
412 break;
413 }
414}
415
416uint8_t GBMBC7Read(struct GBMemory* memory, uint16_t address) {
417 struct GBMBC7State* mbc7 = &memory->mbcState.mbc7;
418 switch (address & 0xF0) {
419 case 0x00:
420 case 0x10:
421 case 0x60:
422 case 0x70:
423 return 0;
424 case 0x20:
425 if (memory->rotation && memory->rotation->readTiltX) {
426 int32_t x = -memory->rotation->readTiltX(memory->rotation);
427 x >>= 21;
428 x += 2047;
429 return x;
430 }
431 return 0xFF;
432 case 0x30:
433 if (memory->rotation && memory->rotation->readTiltX) {
434 int32_t x = -memory->rotation->readTiltX(memory->rotation);
435 x >>= 21;
436 x += 2047;
437 return x >> 8;
438 }
439 return 7;
440 case 0x40:
441 if (memory->rotation && memory->rotation->readTiltY) {
442 int32_t y = -memory->rotation->readTiltY(memory->rotation);
443 y >>= 21;
444 y += 2047;
445 return y;
446 }
447 return 0xFF;
448 case 0x50:
449 if (memory->rotation && memory->rotation->readTiltY) {
450 int32_t y = -memory->rotation->readTiltY(memory->rotation);
451 y >>= 21;
452 y += 2047;
453 return y >> 8;
454 }
455 return 7;
456 case 0x80:
457 return (mbc7->sr >> 16) & 1;
458 default:
459 return 0xFF;
460 }
461}
462
463void GBMBC7Write(struct GBMemory* memory, uint16_t address, uint8_t value) {
464 if ((address & 0xF0) != 0x80) {
465 return;
466 }
467 struct GBMBC7State* mbc7 = &memory->mbcState.mbc7;
468 GBMBC7Field old = memory->mbcState.mbc7.field;
469 mbc7->field = GBMBC7FieldClearIO(value);
470 if (!GBMBC7FieldIsCS(old) && GBMBC7FieldIsCS(value)) {
471 if (mbc7->state == GBMBC7_STATE_WRITE) {
472 if (mbc7->writable) {
473 memory->sramBank[mbc7->address * 2] = mbc7->sr >> 8;
474 memory->sramBank[mbc7->address * 2 + 1] = mbc7->sr;
475 }
476 mbc7->sr = 0x1FFFF;
477 mbc7->state = GBMBC7_STATE_NULL;
478 } else {
479 mbc7->state = GBMBC7_STATE_IDLE;
480 }
481 }
482 if (!GBMBC7FieldIsSK(old) && GBMBC7FieldIsSK(value)) {
483 if (mbc7->state > GBMBC7_STATE_IDLE && mbc7->state != GBMBC7_STATE_READ) {
484 mbc7->sr <<= 1;
485 mbc7->sr |= GBMBC7FieldGetIO(value);
486 ++mbc7->srBits;
487 }
488 switch (mbc7->state) {
489 case GBMBC7_STATE_IDLE:
490 if (GBMBC7FieldIsIO(value)) {
491 mbc7->state = GBMBC7_STATE_READ_COMMAND;
492 mbc7->srBits = 0;
493 mbc7->sr = 0;
494 }
495 break;
496 case GBMBC7_STATE_READ_COMMAND:
497 if (mbc7->srBits == 2) {
498 mbc7->state = GBMBC7_STATE_READ_ADDRESS;
499 mbc7->srBits = 0;
500 mbc7->command = mbc7->sr;
501 }
502 break;
503 case GBMBC7_STATE_READ_ADDRESS:
504 if (mbc7->srBits == 8) {
505 mbc7->state = GBMBC7_STATE_COMMAND_0 + mbc7->command;
506 mbc7->srBits = 0;
507 mbc7->address = mbc7->sr;
508 if (mbc7->state == GBMBC7_STATE_COMMAND_0) {
509 switch (mbc7->address >> 6) {
510 case 0:
511 mbc7->writable = false;
512 mbc7->state = GBMBC7_STATE_NULL;
513 break;
514 case 3:
515 mbc7->writable = true;
516 mbc7->state = GBMBC7_STATE_NULL;
517 break;
518 }
519 }
520 }
521 break;
522 case GBMBC7_STATE_COMMAND_0:
523 if (mbc7->srBits == 16) {
524 switch (mbc7->address >> 6) {
525 case 0:
526 mbc7->writable = false;
527 mbc7->state = GBMBC7_STATE_NULL;
528 break;
529 case 1:
530 mbc7->state = GBMBC7_STATE_WRITE;
531 if (mbc7->writable) {
532 int i;
533 for (i = 0; i < 256; ++i) {
534 memory->sramBank[i * 2] = mbc7->sr >> 8;
535 memory->sramBank[i * 2 + 1] = mbc7->sr;
536 }
537 }
538 break;
539 case 2:
540 mbc7->state = GBMBC7_STATE_WRITE;
541 if (mbc7->writable) {
542 int i;
543 for (i = 0; i < 256; ++i) {
544 memory->sramBank[i * 2] = 0xFF;
545 memory->sramBank[i * 2 + 1] = 0xFF;
546 }
547 }
548 break;
549 case 3:
550 mbc7->writable = true;
551 mbc7->state = GBMBC7_STATE_NULL;
552 break;
553 }
554 }
555 break;
556 case GBMBC7_STATE_COMMAND_SR_WRITE:
557 if (mbc7->srBits == 16) {
558 mbc7->srBits = 0;
559 mbc7->state = GBMBC7_STATE_WRITE;
560 }
561 break;
562 case GBMBC7_STATE_COMMAND_SR_READ:
563 if (mbc7->srBits == 1) {
564 mbc7->sr = memory->sramBank[mbc7->address * 2] << 8;
565 mbc7->sr |= memory->sramBank[mbc7->address * 2 + 1];
566 mbc7->srBits = 0;
567 mbc7->state = GBMBC7_STATE_READ;
568 }
569 break;
570 case GBMBC7_STATE_COMMAND_SR_FILL:
571 if (mbc7->srBits == 16) {
572 mbc7->sr = 0xFFFF;
573 mbc7->srBits = 0;
574 mbc7->state = GBMBC7_STATE_WRITE;
575 }
576 break;
577 default:
578 break;
579 }
580 } else if (GBMBC7FieldIsSK(old) && !GBMBC7FieldIsSK(value)) {
581 if (mbc7->state == GBMBC7_STATE_READ) {
582 mbc7->sr <<= 1;
583 ++mbc7->srBits;
584 if (mbc7->srBits == 16) {
585 mbc7->srBits = 0;
586 mbc7->state = GBMBC7_STATE_NULL;
587 }
588 }
589 }
590}
591
592void _GBHuC3(struct GB* gb, uint16_t address, uint8_t value) {
593 struct GBMemory* memory = &gb->memory;
594 int bank = value & 0x3F;
595 if (address & 0x1FFF) {
596 mLOG(GB_MBC, STUB, "HuC-3 unknown value %04X:%02X", address, value);
597 }
598
599 switch (address >> 13) {
600 case 0x0:
601 switch (value) {
602 case 0xA:
603 memory->sramAccess = true;
604 GBMBCSwitchSramBank(gb, memory->sramCurrentBank);
605 break;
606 default:
607 memory->sramAccess = false;
608 break;
609 }
610 break;
611 case 0x1:
612 GBMBCSwitchBank(memory, bank);
613 break;
614 case 0x2:
615 GBMBCSwitchSramBank(gb, bank);
616 break;
617 default:
618 // TODO
619 mLOG(GB_MBC, STUB, "HuC-3 unknown address: %04X:%02X", address, value);
620 break;
621 }
622}
623
624void GBMBCRTCRead(struct GB* gb) {
625 struct GBMBCRTCSaveBuffer rtcBuffer;
626 struct VFile* vf = gb->sramVf;
627 if (!vf) {
628 return;
629 }
630 ssize_t end = vf->seek(vf, -sizeof(rtcBuffer), SEEK_END);
631 switch (end & 0x1FFF) {
632 case 0:
633 break;
634 case 0x1FFC:
635 vf->seek(vf, -sizeof(rtcBuffer) - 4, SEEK_END);
636 break;
637 default:
638 return;
639 }
640 vf->read(vf, &rtcBuffer, sizeof(rtcBuffer));
641
642 LOAD_32LE(gb->memory.rtcRegs[0], 0, &rtcBuffer.latchedSec);
643 LOAD_32LE(gb->memory.rtcRegs[1], 0, &rtcBuffer.latchedMin);
644 LOAD_32LE(gb->memory.rtcRegs[2], 0, &rtcBuffer.latchedHour);
645 LOAD_32LE(gb->memory.rtcRegs[3], 0, &rtcBuffer.latchedDays);
646 LOAD_32LE(gb->memory.rtcRegs[4], 0, &rtcBuffer.latchedDaysHi);
647 LOAD_64LE(gb->memory.rtcLastLatch, 0, &rtcBuffer.unixTime);
648}
649
650void GBMBCRTCWrite(struct GB* gb) {
651 struct VFile* vf = gb->sramVf;
652 if (!vf) {
653 return;
654 }
655
656 uint8_t rtcRegs[5];
657 memcpy(rtcRegs, gb->memory.rtcRegs, sizeof(rtcRegs));
658 time_t rtcLastLatch = gb->memory.rtcLastLatch;
659 _latchRtc(gb->memory.rtc, rtcRegs, &rtcLastLatch);
660
661 struct GBMBCRTCSaveBuffer rtcBuffer;
662 STORE_32LE(rtcRegs[0], 0, &rtcBuffer.sec);
663 STORE_32LE(rtcRegs[1], 0, &rtcBuffer.min);
664 STORE_32LE(rtcRegs[2], 0, &rtcBuffer.hour);
665 STORE_32LE(rtcRegs[3], 0, &rtcBuffer.days);
666 STORE_32LE(rtcRegs[4], 0, &rtcBuffer.daysHi);
667 STORE_32LE(gb->memory.rtcRegs[0], 0, &rtcBuffer.latchedSec);
668 STORE_32LE(gb->memory.rtcRegs[1], 0, &rtcBuffer.latchedMin);
669 STORE_32LE(gb->memory.rtcRegs[2], 0, &rtcBuffer.latchedHour);
670 STORE_32LE(gb->memory.rtcRegs[3], 0, &rtcBuffer.latchedDays);
671 STORE_32LE(gb->memory.rtcRegs[4], 0, &rtcBuffer.latchedDaysHi);
672 STORE_64LE(rtcLastLatch, 0, &rtcBuffer.unixTime);
673
674 if (vf->size(vf) == gb->sramSize) {
675 // Writing past the end of the file can invalidate the file mapping
676 vf->unmap(vf, gb->memory.sram, gb->sramSize);
677 gb->memory.sram = NULL;
678 }
679 vf->seek(vf, gb->sramSize, SEEK_SET);
680 vf->write(vf, &rtcBuffer, sizeof(rtcBuffer));
681 if (!gb->memory.sram) {
682 gb->memory.sram = vf->map(vf, gb->sramSize, MAP_WRITE);
683 GBMBCSwitchSramBank(gb, gb->memory.sramCurrentBank);
684 }
685}