all repos — mgba @ e88d1775827589a15eb41511802a0b6fb16dec1e

mGBA Game Boy Advance Emulator

src/gba/gba-memory.c (view raw)

  1#include "gba-memory.h"
  2
  3#include "gba-io.h"
  4
  5#include <limits.h>
  6#include <string.h>
  7#include <sys/mman.h>
  8
  9static const char* GBA_CANNOT_MMAP = "Could not map memory";
 10
 11static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t region);
 12
 13static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
 14static const char GBA_BASE_WAITSTATES_SEQ[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4 };
 15static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
 16static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
 17static const int DMA_OFFSET[] = { 1, -1, 0, 1 };
 18
 19void GBAMemoryInit(struct GBAMemory* memory) {
 20	memory->d.load32 = GBALoad32;
 21	memory->d.load16 = GBALoad16;
 22	memory->d.loadU16 = GBALoadU16;
 23	memory->d.load8 = GBALoad8;
 24	memory->d.loadU8 = GBALoadU8;
 25	memory->d.store32 = GBAStore32;
 26	memory->d.store16 = GBAStore16;
 27	memory->d.store8 = GBAStore8;
 28
 29	memory->bios = 0;
 30	memory->wram = mmap(0, SIZE_WORKING_RAM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
 31	memory->iwram = mmap(0, SIZE_WORKING_IRAM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
 32	memory->rom = 0;
 33	memset(memory->io, 0, sizeof(memory->io));
 34	memset(memory->dma, 0, sizeof(memory->dma));
 35
 36	if (!memory->wram || !memory->iwram) {
 37		GBAMemoryDeinit(memory);
 38		memory->p->errno = GBA_OUT_OF_MEMORY;
 39		memory->p->errstr = GBA_CANNOT_MMAP;
 40	}
 41
 42	int i;
 43	for (i = 0; i < 16; ++i) {
 44		memory->waitstates16[i] = GBA_BASE_WAITSTATES[i];
 45		memory->waitstatesSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
 46		memory->waitstates32[i] = GBA_BASE_WAITSTATES[i] + GBA_BASE_WAITSTATES_SEQ[i] + 1;
 47		memory->waitstatesSeq32[i] = GBA_BASE_WAITSTATES_SEQ[i] + GBA_BASE_WAITSTATES_SEQ[i] + 1;
 48	}
 49	for (; i < 256; ++i) {
 50		memory->waitstates16[i] = 0;
 51		memory->waitstatesSeq16[i] = 0;
 52		memory->waitstates32[i] = 0;
 53		memory->waitstatesSeq32[i] = 0;
 54	}
 55
 56	memory->activeRegion = 0;
 57	memory->d.activeRegion = 0;
 58	memory->d.activeMask = 0;
 59	memory->d.setActiveRegion = GBASetActiveRegion;
 60	memory->d.activePrefetchCycles32 = 0;
 61	memory->d.activePrefetchCycles16 = 0;
 62}
 63
 64void GBAMemoryDeinit(struct GBAMemory* memory) {
 65	munmap(memory->wram, SIZE_WORKING_RAM);
 66	munmap(memory->iwram, SIZE_WORKING_IRAM);
 67}
 68
 69static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t address) {
 70	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
 71
 72	memory->activePrefetchCycles32 = gbaMemory->waitstates32[address >> BASE_OFFSET];
 73	memory->activePrefetchCycles16 = gbaMemory->waitstates16[address >> BASE_OFFSET];
 74	gbaMemory->activeRegion = address >> BASE_OFFSET;
 75	switch (address & ~OFFSET_MASK) {
 76	case BASE_BIOS:
 77		memory->activeRegion = gbaMemory->bios;
 78		memory->activeMask = 0;
 79		break;
 80	case BASE_WORKING_RAM:
 81		memory->activeRegion = gbaMemory->wram;
 82		memory->activeMask = SIZE_WORKING_RAM - 1;
 83		break;
 84	case BASE_WORKING_IRAM:
 85		memory->activeRegion = gbaMemory->iwram;
 86		memory->activeMask = SIZE_WORKING_IRAM - 1;
 87		break;
 88	case BASE_CART0:
 89	case BASE_CART0_EX:
 90	case BASE_CART1:
 91	case BASE_CART1_EX:
 92	case BASE_CART2:
 93	case BASE_CART2_EX:
 94		memory->activeRegion = gbaMemory->rom;
 95		memory->activeMask = SIZE_CART0 - 1;
 96		break;
 97	default:
 98		memory->activeRegion = 0;
 99		memory->activeMask = 0;
100		break;
101	}
102}
103
104int32_t GBALoad32(struct ARMMemory* memory, uint32_t address) {
105	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
106
107	switch (address & ~OFFSET_MASK) {
108	case BASE_BIOS:
109		break;
110	case BASE_WORKING_RAM:
111		return gbaMemory->wram[(address & (SIZE_WORKING_RAM - 1)) >> 2];
112	case BASE_WORKING_IRAM:
113		return gbaMemory->iwram[(address & (SIZE_WORKING_IRAM - 1)) >> 2];
114	case BASE_IO:
115		break;
116	case BASE_PALETTE_RAM:
117		break;
118	case BASE_VRAM:
119		break;
120	case BASE_OAM:
121		break;
122	case BASE_CART0:
123	case BASE_CART0_EX:
124	case BASE_CART1:
125	case BASE_CART1_EX:
126	case BASE_CART2:
127	case BASE_CART2_EX:
128		return gbaMemory->rom[(address & (SIZE_CART0 - 1)) >> 2];
129	case BASE_CART_SRAM:
130		break;
131	default:
132		break;
133	}
134
135	return 0;
136}
137
138int16_t GBALoad16(struct ARMMemory* memory, uint32_t address) {
139	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
140
141	switch (address & ~OFFSET_MASK) {
142	case BASE_BIOS:
143		break;
144	case BASE_WORKING_RAM:
145		return ((int16_t*) gbaMemory->wram)[(address & (SIZE_WORKING_RAM - 1)) >> 1];
146	case BASE_WORKING_IRAM:
147		return ((int16_t*) gbaMemory->iwram)[(address & (SIZE_WORKING_IRAM - 1)) >> 1];
148	case BASE_IO:
149		return GBAIORead(gbaMemory->p, address & (SIZE_IO - 1));
150	case BASE_PALETTE_RAM:
151		break;
152	case BASE_VRAM:
153		break;
154	case BASE_OAM:
155		break;
156	case BASE_CART0:
157	case BASE_CART0_EX:
158	case BASE_CART1:
159	case BASE_CART1_EX:
160	case BASE_CART2:
161	case BASE_CART2_EX:
162		return ((int16_t*) gbaMemory->rom)[(address & (SIZE_CART0 - 1)) >> 1];
163	case BASE_CART_SRAM:
164		break;
165	default:
166		break;
167	}
168
169	return 0;
170}
171
172uint16_t GBALoadU16(struct ARMMemory* memory, uint32_t address) {
173	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
174
175	switch (address & ~OFFSET_MASK) {
176	case BASE_BIOS:
177		break;
178	case BASE_WORKING_RAM:
179		return ((uint16_t*) gbaMemory->wram)[(address & (SIZE_WORKING_RAM - 1)) >> 1];
180	case BASE_WORKING_IRAM:
181		return ((uint16_t*) gbaMemory->iwram)[(address & (SIZE_WORKING_IRAM - 1)) >> 1];
182	case BASE_IO:
183		return GBAIORead(gbaMemory->p, address & (SIZE_IO - 1));
184	case BASE_PALETTE_RAM:
185		break;
186	case BASE_VRAM:
187		break;
188	case BASE_OAM:
189		break;
190	case BASE_CART0:
191	case BASE_CART0_EX:
192	case BASE_CART1:
193	case BASE_CART1_EX:
194	case BASE_CART2:
195	case BASE_CART2_EX:
196		return ((uint16_t*) gbaMemory->rom)[(address & (SIZE_CART0 - 1)) >> 1];
197	case BASE_CART_SRAM:
198		break;
199	default:
200		break;
201	}
202
203	return 0;
204}
205
206int8_t GBALoad8(struct ARMMemory* memory, uint32_t address) {
207	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
208
209	switch (address & ~OFFSET_MASK) {
210	case BASE_BIOS:
211		break;
212	case BASE_WORKING_RAM:
213		return ((int8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)];
214	case BASE_WORKING_IRAM:
215		return ((int8_t*) gbaMemory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
216	case BASE_IO:
217		break;
218	case BASE_PALETTE_RAM:
219		break;
220	case BASE_VRAM:
221		break;
222	case BASE_OAM:
223		break;
224	case BASE_CART0:
225	case BASE_CART0_EX:
226	case BASE_CART1:
227	case BASE_CART1_EX:
228	case BASE_CART2:
229	case BASE_CART2_EX:
230		return ((int8_t*) gbaMemory->rom)[address & (SIZE_CART0 - 1)];
231	case BASE_CART_SRAM:
232		break;
233	default:
234		break;
235	}
236
237	return 0;
238}
239
240uint8_t GBALoadU8(struct ARMMemory* memory, uint32_t address) {
241	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
242
243	switch (address & ~OFFSET_MASK) {
244	case BASE_BIOS:
245		break;
246	case BASE_WORKING_RAM:
247		return ((uint8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)];
248		break;
249	case BASE_WORKING_IRAM:
250		return ((uint8_t*) gbaMemory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
251		break;
252	case BASE_IO:
253		break;
254	case BASE_PALETTE_RAM:
255		break;
256	case BASE_VRAM:
257		break;
258	case BASE_OAM:
259		break;
260	case BASE_CART0:
261	case BASE_CART0_EX:
262	case BASE_CART1:
263	case BASE_CART1_EX:
264	case BASE_CART2:
265	case BASE_CART2_EX:
266		return ((uint8_t*) gbaMemory->rom)[address & (SIZE_CART0 - 1)];
267	case BASE_CART_SRAM:
268		break;
269	default:
270		break;
271	}
272
273	return 0;
274}
275
276void GBAStore32(struct ARMMemory* memory, uint32_t address, int32_t value) {
277	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
278
279	switch (address & ~OFFSET_MASK) {
280	case BASE_WORKING_RAM:
281		gbaMemory->wram[(address & (SIZE_WORKING_RAM - 1)) >> 2] = value;
282		break;
283	case BASE_WORKING_IRAM:
284		gbaMemory->iwram[(address & (SIZE_WORKING_IRAM - 1)) >> 2] = value;
285		break;
286	case BASE_IO:
287		GBAIOWrite32(gbaMemory->p, address & (SIZE_IO - 1), value);
288		break;
289	case BASE_PALETTE_RAM:
290		break;
291	case BASE_VRAM:
292		break;
293	case BASE_OAM:
294		break;
295	case BASE_CART0:
296		break;
297	case BASE_CART2_EX:
298		break;
299	case BASE_CART_SRAM:
300		break;
301	default:
302		break;
303	}
304}
305
306void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value) {
307	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
308
309	switch (address & ~OFFSET_MASK) {
310	case BASE_WORKING_RAM:
311		((int16_t*) gbaMemory->wram)[(address & (SIZE_WORKING_RAM - 1)) >> 1] = value;
312		break;
313	case BASE_WORKING_IRAM:
314		((int16_t*) gbaMemory->iwram)[(address & (SIZE_WORKING_IRAM - 1)) >> 1] = value;
315		break;
316	case BASE_IO:
317		GBAIOWrite(gbaMemory->p, address & (SIZE_IO - 1), value);
318		break;
319	case BASE_PALETTE_RAM:
320		break;
321	case BASE_VRAM:
322		break;
323	case BASE_OAM:
324		break;
325	case BASE_CART0:
326		break;
327	case BASE_CART2_EX:
328		break;
329	case BASE_CART_SRAM:
330		break;
331	default:
332		break;
333	}
334}
335
336void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value) {
337	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
338
339	switch (address & ~OFFSET_MASK) {
340	case BASE_WORKING_RAM:
341		((int8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
342		break;
343	case BASE_WORKING_IRAM:
344		((int8_t*) gbaMemory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
345		break;
346	case BASE_IO:
347		break;
348	case BASE_PALETTE_RAM:
349		break;
350	case BASE_VRAM:
351		break;
352	case BASE_OAM:
353		break;
354	case BASE_CART0:
355		break;
356	case BASE_CART2_EX:
357		break;
358	case BASE_CART_SRAM:
359		break;
360	default:
361		break;
362	}
363}
364
365void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters) {
366	int sram = parameters & 0x0003;
367	int ws0 = (parameters & 0x000C) >> 2;
368	int ws0seq = (parameters & 0x0010) >> 4;
369	int ws1 = (parameters & 0x0060) >> 5;
370	int ws1seq = (parameters & 0x0080) >> 7;
371	int ws2 = (parameters & 0x0300) >> 8;
372	int ws2seq = (parameters & 0x0400) >> 10;
373	int prefetch = parameters & 0x4000;
374
375	memory->waitstates16[REGION_CART_SRAM] =  GBA_ROM_WAITSTATES[sram];
376	memory->waitstatesSeq16[REGION_CART_SRAM] = GBA_ROM_WAITSTATES[sram];
377	memory->waitstates32[REGION_CART_SRAM] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
378	memory->waitstatesSeq32[REGION_CART_SRAM] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
379
380	memory->waitstates16[REGION_CART0] = memory->waitstates16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
381	memory->waitstates16[REGION_CART1] = memory->waitstates16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
382	memory->waitstates16[REGION_CART2] = memory->waitstates16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
383
384	memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
385	memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
386	memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
387
388	memory->waitstates32[REGION_CART0] = memory->waitstates32[REGION_CART0_EX] = memory->waitstates16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
389	memory->waitstates32[REGION_CART1] = memory->waitstates32[REGION_CART1_EX] = memory->waitstates16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
390	memory->waitstates32[REGION_CART2] = memory->waitstates32[REGION_CART2_EX] = memory->waitstates16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
391
392	memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0 + 1] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
393	memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1 + 1] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
394	memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2 + 1] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
395
396	memory->d.activePrefetchCycles32 = memory->waitstates32[memory->activeRegion];
397	memory->d.activePrefetchCycles16 = memory->waitstates16[memory->activeRegion];
398}
399
400int32_t GBAMemoryProcessEvents(struct GBAMemory* memory, int32_t cycles) {
401	struct GBADMA* dma;
402	int32_t test = INT_MAX;
403
404	dma = &memory->dma[0];
405	dma->nextIRQ -= cycles;
406	if (dma->enable && dma->doIrq && dma->nextIRQ) {
407		if (dma->nextIRQ <= 0) {
408			dma->nextIRQ = INT_MAX;
409			GBARaiseIRQ(memory->p, IRQ_DMA0);
410		} else if (dma->nextIRQ < test) {
411			test = dma->nextIRQ;
412		}
413	}
414
415	dma = &memory->dma[1];
416	dma->nextIRQ -= cycles;
417	if (dma->enable && dma->doIrq && dma->nextIRQ) {
418		if (dma->nextIRQ <= 0) {
419			dma->nextIRQ = INT_MAX;
420			GBARaiseIRQ(memory->p, IRQ_DMA1);
421		} else if (dma->nextIRQ < test) {
422			test = dma->nextIRQ;
423		}
424	}
425
426	dma = &memory->dma[2];
427	dma->nextIRQ -= cycles;
428	if (dma->enable && dma->doIrq && dma->nextIRQ) {
429		if (dma->nextIRQ <= 0) {
430			dma->nextIRQ = INT_MAX;
431			GBARaiseIRQ(memory->p, IRQ_DMA2);
432		} else if (dma->nextIRQ < test) {
433			test = dma->nextIRQ;
434		}
435	}
436
437	dma = &memory->dma[3];
438	dma->nextIRQ -= cycles;
439	if (dma->enable && dma->doIrq && dma->nextIRQ) {
440		if (dma->nextIRQ <= 0) {
441			dma->nextIRQ = INT_MAX;
442			GBARaiseIRQ(memory->p, IRQ_DMA3);
443		} else if (dma->nextIRQ < test) {
444			test = dma->nextIRQ;
445		}
446	}
447
448	return test;
449}
450
451void GBAMemoryWriteDMASAD(struct GBAMemory* memory, int dma, uint32_t address) {
452	memory->dma[dma].source = address & 0xFFFFFFFE;
453}
454
455void GBAMemoryWriteDMADAD(struct GBAMemory* memory, int dma, uint32_t address) {
456	memory->dma[dma].dest = address & 0xFFFFFFFE;
457}
458
459void GBAMemoryWriteDMACNT_LO(struct GBAMemory* memory, int dma, uint16_t count) {
460	memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
461}
462
463void GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control) {
464	struct GBADMA* currentDma = &memory->dma[dma];
465	int wasEnabled = currentDma->enable;
466	currentDma->packed = control;
467	currentDma->nextIRQ = 0;
468
469	if (currentDma->drq) {
470		GBALog(GBA_LOG_STUB, "DRQ not implemented");
471	}
472
473	if (!wasEnabled && currentDma->enable) {
474		currentDma->nextSource = currentDma->source;
475		currentDma->nextDest = currentDma->dest;
476		currentDma->nextCount = currentDma->count;
477		GBAMemoryScheduleDMA(memory, dma, currentDma);
478	}
479};
480
481void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* info) {
482	switch (info->timing) {
483	case DMA_TIMING_NOW:
484		GBAMemoryServiceDMA(memory, number, info);
485		break;
486	case DMA_TIMING_HBLANK:
487		// Handled implicitly
488		break;
489	case DMA_TIMING_VBLANK:
490		// Handled implicitly
491		break;
492	case DMA_TIMING_CUSTOM:
493		switch (number) {
494		case 0:
495			GBALog(GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
496			break;
497		case 1:
498		case 2:
499			//this.cpu.irq.audio.scheduleFIFODma(number, info);
500			break;
501		case 3:
502			//this.cpu.irq.video.scheduleVCaptureDma(dma, info);
503			break;
504		}
505	}
506}
507
508void GBAMemoryRunHblankDMAs(struct GBAMemory* memory) {
509	struct GBADMA* dma;
510	int i;
511	for (i = 0; i < 4; ++i) {
512		dma = &memory->dma[i];
513		if (dma->enable && dma->timing == DMA_TIMING_HBLANK) {
514			GBAMemoryServiceDMA(memory, i, dma);
515		}
516	}
517}
518
519void GBAMemoryRunVblankDMAs(struct GBAMemory* memory) {
520	struct GBADMA* dma;
521	int i;
522	for (i = 0; i < 4; ++i) {
523		dma = &memory->dma[i];
524		if (dma->enable && dma->timing == DMA_TIMING_VBLANK) {
525			GBAMemoryServiceDMA(memory, i, dma);
526		}
527	}
528}
529
530void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* info) {
531	if (!info->enable) {
532		// There was a DMA scheduled that got canceled
533		return;
534	}
535
536	uint32_t width = info->width ? 4 : 2;
537	int sourceOffset = DMA_OFFSET[info->srcControl] * width;
538	int destOffset = DMA_OFFSET[info->dstControl] * width;
539	int32_t wordsRemaining = info->nextCount;
540	uint32_t source = info->nextSource;
541	uint32_t dest = info->nextDest;
542	uint32_t sourceRegion = source >> BASE_OFFSET;
543	uint32_t destRegion = dest >> BASE_OFFSET;
544
545	if (width == 4) {
546		int32_t word;
547		source &= 0xFFFFFFFC;
548		dest &= 0xFFFFFFFC;
549		while (wordsRemaining--) {
550			word = GBALoad32(&memory->d, source);
551			GBAStore32(&memory->d, dest, word);
552			source += sourceOffset;
553			dest += destOffset;
554		}
555	} else {
556		uint16_t word;
557		while (wordsRemaining--) {
558			word = GBALoadU16(&memory->d, source);
559			GBAStore16(&memory->d, dest, word);
560			source += sourceOffset;
561			dest += destOffset;
562		}
563	}
564
565	if (info->doIrq) {
566		info->nextIRQ = memory->p->cpu.cycles + 2;
567		info->nextIRQ += (width == 4 ? memory->waitstates32[sourceRegion] + memory->waitstates32[destRegion]
568		                            : memory->waitstates16[sourceRegion] + memory->waitstates16[destRegion]);
569		info->nextIRQ += (info->count - 1) * (width == 4 ? memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion]
570		                                               : memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion]);
571	}
572
573	info->nextSource = source;
574	info->nextDest = dest;
575	info->nextCount = wordsRemaining;
576
577	if (!info->repeat) {
578		info->enable = 0;
579
580		// Clear the enable bit in memory
581		memory->io[(REG_DMA0CNT_HI + number * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
582	} else {
583		info->nextCount = info->count;
584		if (info->dstControl == DMA_INCREMENT_RELOAD) {
585			info->nextDest = info->dest;
586		}
587		GBAMemoryScheduleDMA(memory, number, info);
588	}
589}