all repos — mgba @ eec39a4324386a8b853e871c23ed79b09bc397d2

mGBA Game Boy Advance Emulator

src/gb/io.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 <mgba/internal/gb/io.h>
  7
  8#include <mgba/internal/gb/gb.h>
  9#include <mgba/internal/gb/sio.h>
 10#include <mgba/internal/gb/serialize.h>
 11
 12mLOG_DEFINE_CATEGORY(GB_IO, "GB I/O", "gb.io");
 13
 14const char* const GBIORegisterNames[] = {
 15	[REG_JOYP] = "JOYP",
 16	[REG_SB] = "SB",
 17	[REG_SC] = "SC",
 18	[REG_DIV] = "DIV",
 19	[REG_TIMA] = "TIMA",
 20	[REG_TMA] = "TMA",
 21	[REG_TAC] = "TAC",
 22	[REG_IF] = "IF",
 23	[REG_NR10] = "NR10",
 24	[REG_NR11] = "NR11",
 25	[REG_NR12] = "NR12",
 26	[REG_NR13] = "NR13",
 27	[REG_NR14] = "NR14",
 28	[REG_NR21] = "NR21",
 29	[REG_NR22] = "NR22",
 30	[REG_NR23] = "NR23",
 31	[REG_NR24] = "NR24",
 32	[REG_NR30] = "NR30",
 33	[REG_NR31] = "NR31",
 34	[REG_NR32] = "NR32",
 35	[REG_NR33] = "NR33",
 36	[REG_NR34] = "NR34",
 37	[REG_NR41] = "NR41",
 38	[REG_NR42] = "NR42",
 39	[REG_NR43] = "NR43",
 40	[REG_NR44] = "NR44",
 41	[REG_NR50] = "NR50",
 42	[REG_NR51] = "NR51",
 43	[REG_NR52] = "NR52",
 44	[REG_LCDC] = "LCDC",
 45	[REG_STAT] = "STAT",
 46	[REG_SCY] = "SCY",
 47	[REG_SCX] = "SCX",
 48	[REG_LY] = "LY",
 49	[REG_LYC] = "LYC",
 50	[REG_DMA] = "DMA",
 51	[REG_BGP] = "BGP",
 52	[REG_OBP0] = "OBP0",
 53	[REG_OBP1] = "OBP1",
 54	[REG_WY] = "WY",
 55	[REG_WX] = "WX",
 56	[REG_KEY1] = "KEY1",
 57	[REG_VBK] = "VBK",
 58	[REG_HDMA1] = "HDMA1",
 59	[REG_HDMA2] = "HDMA2",
 60	[REG_HDMA3] = "HDMA3",
 61	[REG_HDMA4] = "HDMA4",
 62	[REG_HDMA5] = "HDMA5",
 63	[REG_RP] = "RP",
 64	[REG_BCPS] = "BCPS",
 65	[REG_BCPD] = "BCPD",
 66	[REG_OCPS] = "OCPS",
 67	[REG_OCPD] = "OCPD",
 68	[REG_SVBK] = "SVBK",
 69	[REG_IE] = "IE",
 70};
 71
 72static const uint8_t _registerMask[] = {
 73	[REG_SC]   = 0x7E, // TODO: GBC differences
 74	[REG_IF]   = 0xE0,
 75	[REG_TAC]  = 0xF8,
 76	[REG_NR10] = 0x80,
 77	[REG_NR11] = 0x3F,
 78	[REG_NR12] = 0x00,
 79	[REG_NR13] = 0xFF,
 80	[REG_NR14] = 0xBF,
 81	[REG_NR21] = 0x3F,
 82	[REG_NR22] = 0x00,
 83	[REG_NR23] = 0xFF,
 84	[REG_NR24] = 0xBF,
 85	[REG_NR30] = 0x7F,
 86	[REG_NR31] = 0xFF,
 87	[REG_NR32] = 0x9F,
 88	[REG_NR33] = 0xFF,
 89	[REG_NR34] = 0xBF,
 90	[REG_NR41] = 0xFF,
 91	[REG_NR42] = 0x00,
 92	[REG_NR43] = 0x00,
 93	[REG_NR44] = 0xBF,
 94	[REG_NR50] = 0x00,
 95	[REG_NR51] = 0x00,
 96	[REG_NR52] = 0x70,
 97	[REG_STAT] = 0x80,
 98	[REG_KEY1] = 0x7E,
 99	[REG_VBK] = 0xFE,
100	[REG_OCPS] = 0x40,
101	[REG_BCPS] = 0x40,
102	[REG_UNK6C] = 0xFE,
103	[REG_SVBK] = 0xF8,
104	[REG_IE]   = 0xE0,
105};
106
107static uint8_t _readKeys(struct GB* gb);
108
109static void _writeSGBBits(struct GB* gb, int bits) {
110	if (!bits) {
111		gb->sgbBit = -1;
112		memset(gb->sgbPacket, 0, sizeof(gb->sgbPacket));
113	}
114	if (bits == gb->currentSgbBits) {
115		return;
116	}
117	gb->currentSgbBits = bits;
118	if (gb->sgbBit > 128) {
119		switch (bits) {
120		case 1:
121			gb->sgbBit |= 2;
122			break;
123		case 2:
124			gb->sgbBit |= 4;
125			break;
126		case 3:
127			if (gb->sgbBit == 135) {
128				gb->sgbBit &= ~6;
129				gb->sgbCurrentController = (gb->sgbCurrentController + 1) & gb->sgbControllers;
130			}
131			break;
132		}
133	}
134	if (gb->sgbBit == 128 && bits == 2) {
135		GBVideoWriteSGBPacket(&gb->video, gb->sgbPacket);
136		++gb->sgbBit;
137	}
138	if (gb->sgbBit >= 128) {
139		return;
140	}
141	switch (bits) {
142	case 1:
143		if (gb->sgbBit < 0) {
144			return;
145		}
146		gb->sgbPacket[gb->sgbBit >> 3] |= 1 << (gb->sgbBit & 7);
147		break;
148	case 3:
149		++gb->sgbBit;
150	default:
151		break;
152	}
153}
154
155void GBIOInit(struct GB* gb) {
156	memset(gb->memory.io, 0, sizeof(gb->memory.io));
157}
158
159void GBIOReset(struct GB* gb) {
160	memset(gb->memory.io, 0, sizeof(gb->memory.io));
161
162	GBIOWrite(gb, REG_TIMA, 0);
163	GBIOWrite(gb, REG_TMA, 0);
164	GBIOWrite(gb, REG_TAC, 0);
165	GBIOWrite(gb, REG_IF, 1);
166	GBIOWrite(gb, REG_NR52, 0xF1);
167	GBIOWrite(gb, REG_NR14, 0x3F);
168	GBIOWrite(gb, REG_NR10, 0x80);
169	GBIOWrite(gb, REG_NR11, 0xBF);
170	GBIOWrite(gb, REG_NR12, 0xF3);
171	GBIOWrite(gb, REG_NR13, 0xF3);
172	GBIOWrite(gb, REG_NR24, 0x3F);
173	GBIOWrite(gb, REG_NR21, 0x3F);
174	GBIOWrite(gb, REG_NR22, 0x00);
175	GBIOWrite(gb, REG_NR34, 0x3F);
176	GBIOWrite(gb, REG_NR30, 0x7F);
177	GBIOWrite(gb, REG_NR31, 0xFF);
178	GBIOWrite(gb, REG_NR32, 0x9F);
179	GBIOWrite(gb, REG_NR44, 0x3F);
180	GBIOWrite(gb, REG_NR41, 0xFF);
181	GBIOWrite(gb, REG_NR42, 0x00);
182	GBIOWrite(gb, REG_NR43, 0x00);
183	GBIOWrite(gb, REG_NR50, 0x77);
184	GBIOWrite(gb, REG_NR51, 0xF3);
185	if (!gb->biosVf) {
186		GBIOWrite(gb, REG_LCDC, 0x91);
187	} else {
188		GBIOWrite(gb, REG_LCDC, 0x00);
189	}
190	GBIOWrite(gb, REG_SCY, 0x00);
191	GBIOWrite(gb, REG_SCX, 0x00);
192	GBIOWrite(gb, REG_LYC, 0x00);
193	GBIOWrite(gb, REG_DMA, 0xFF);
194	GBIOWrite(gb, REG_BGP, 0xFC);
195	if (gb->model < GB_MODEL_CGB) {
196		GBIOWrite(gb, REG_OBP0, 0xFF);
197		GBIOWrite(gb, REG_OBP1, 0xFF);
198	}
199	GBIOWrite(gb, REG_WY, 0x00);
200	GBIOWrite(gb, REG_WX, 0x00);
201	if (gb->model >= GB_MODEL_CGB) {
202		GBIOWrite(gb, REG_UNK4C, 0);
203		GBIOWrite(gb, REG_JOYP, 0xFF);
204		GBIOWrite(gb, REG_VBK, 0);
205		GBIOWrite(gb, REG_BCPS, 0);
206		GBIOWrite(gb, REG_OCPS, 0);
207		GBIOWrite(gb, REG_SVBK, 1);
208		GBIOWrite(gb, REG_HDMA1, 0xFF);
209		GBIOWrite(gb, REG_HDMA2, 0xFF);
210		GBIOWrite(gb, REG_HDMA3, 0xFF);
211		GBIOWrite(gb, REG_HDMA4, 0xFF);
212		gb->memory.io[REG_HDMA5] = 0xFF;
213	} else if (gb->model == GB_MODEL_SGB) {
214		GBIOWrite(gb, REG_JOYP, 0xFF);
215	}
216	GBIOWrite(gb, REG_IE, 0x00);
217}
218
219void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
220	switch (address) {
221	case REG_SB:
222		GBSIOWriteSB(&gb->sio, value);
223		break;
224	case REG_SC:
225		GBSIOWriteSC(&gb->sio, value);
226		break;
227	case REG_DIV:
228		GBTimerDivReset(&gb->timer);
229		return;
230	case REG_NR10:
231		if (gb->audio.enable) {
232			GBAudioWriteNR10(&gb->audio, value);
233		} else {
234			value = 0;
235		}
236		break;
237	case REG_NR11:
238		if (gb->audio.enable) {
239			GBAudioWriteNR11(&gb->audio, value);
240		} else {
241			if (gb->audio.style == GB_AUDIO_DMG) {
242				GBAudioWriteNR11(&gb->audio, value & _registerMask[REG_NR11]);
243			}
244			value = 0;
245		}
246		break;
247	case REG_NR12:
248		if (gb->audio.enable) {
249			GBAudioWriteNR12(&gb->audio, value);
250		} else {
251			value = 0;
252		}
253		break;
254	case REG_NR13:
255		if (gb->audio.enable) {
256			GBAudioWriteNR13(&gb->audio, value);
257		} else {
258			value = 0;
259		}
260		break;
261	case REG_NR14:
262		if (gb->audio.enable) {
263			GBAudioWriteNR14(&gb->audio, value);
264		} else {
265			value = 0;
266		}
267		break;
268	case REG_NR21:
269		if (gb->audio.enable) {
270			GBAudioWriteNR21(&gb->audio, value);
271		} else {
272			if (gb->audio.style == GB_AUDIO_DMG) {
273				GBAudioWriteNR21(&gb->audio, value & _registerMask[REG_NR21]);
274			}
275			value = 0;
276		}
277		break;
278	case REG_NR22:
279		if (gb->audio.enable) {
280			GBAudioWriteNR22(&gb->audio, value);
281		} else {
282			value = 0;
283		}
284		break;
285	case REG_NR23:
286		if (gb->audio.enable) {
287			GBAudioWriteNR23(&gb->audio, value);
288		} else {
289			value = 0;
290		}
291		break;
292	case REG_NR24:
293		if (gb->audio.enable) {
294			GBAudioWriteNR24(&gb->audio, value);
295		} else {
296			value = 0;
297		}
298		break;
299	case REG_NR30:
300		if (gb->audio.enable) {
301			GBAudioWriteNR30(&gb->audio, value);
302		} else {
303			value = 0;
304		}
305		break;
306	case REG_NR31:
307		if (gb->audio.enable || gb->audio.style == GB_AUDIO_DMG) {
308			GBAudioWriteNR31(&gb->audio, value);
309		} else {
310			value = 0;
311		}
312		break;
313	case REG_NR32:
314		if (gb->audio.enable) {
315			GBAudioWriteNR32(&gb->audio, value);
316		} else {
317			value = 0;
318		}
319		break;
320	case REG_NR33:
321		if (gb->audio.enable) {
322			GBAudioWriteNR33(&gb->audio, value);
323		} else {
324			value = 0;
325		}
326		break;
327	case REG_NR34:
328		if (gb->audio.enable) {
329			GBAudioWriteNR34(&gb->audio, value);
330		} else {
331			value = 0;
332		}
333		break;
334	case REG_NR41:
335		if (gb->audio.enable || gb->audio.style == GB_AUDIO_DMG) {
336			GBAudioWriteNR41(&gb->audio, value);
337		} else {
338			value = 0;
339		}
340		break;
341	case REG_NR42:
342		if (gb->audio.enable) {
343			GBAudioWriteNR42(&gb->audio, value);
344		} else {
345			value = 0;
346		}
347		break;
348	case REG_NR43:
349		if (gb->audio.enable) {
350			GBAudioWriteNR43(&gb->audio, value);
351		} else {
352			value = 0;
353		}
354		break;
355	case REG_NR44:
356		if (gb->audio.enable) {
357			GBAudioWriteNR44(&gb->audio, value);
358		} else {
359			value = 0;
360		}
361		break;
362	case REG_NR50:
363		if (gb->audio.enable) {
364			GBAudioWriteNR50(&gb->audio, value);
365		} else {
366			value = 0;
367		}
368		break;
369	case REG_NR51:
370		if (gb->audio.enable) {
371			GBAudioWriteNR51(&gb->audio, value);
372		} else {
373			value = 0;
374		}
375		break;
376	case REG_NR52:
377		GBAudioWriteNR52(&gb->audio, value);
378		value &= 0x80;
379		value |= gb->memory.io[REG_NR52] & 0x0F;
380		break;
381	case REG_WAVE_0:
382	case REG_WAVE_1:
383	case REG_WAVE_2:
384	case REG_WAVE_3:
385	case REG_WAVE_4:
386	case REG_WAVE_5:
387	case REG_WAVE_6:
388	case REG_WAVE_7:
389	case REG_WAVE_8:
390	case REG_WAVE_9:
391	case REG_WAVE_A:
392	case REG_WAVE_B:
393	case REG_WAVE_C:
394	case REG_WAVE_D:
395	case REG_WAVE_E:
396	case REG_WAVE_F:
397		if (!gb->audio.playingCh3 || gb->audio.style != GB_AUDIO_DMG) {
398			gb->audio.ch3.wavedata8[address - REG_WAVE_0] = value;
399		} else if(gb->audio.ch3.readable) {
400			gb->audio.ch3.wavedata8[gb->audio.ch3.window >> 1] = value;
401		}
402		break;
403	case REG_JOYP:
404		gb->memory.io[REG_JOYP] = value | 0x0F;
405		_readKeys(gb);
406		if (gb->model == GB_MODEL_SGB) {
407			_writeSGBBits(gb, (value >> 4) & 3);
408		}
409		return;
410	case REG_TIMA:
411		if (value && mTimingUntil(&gb->timing, &gb->timer.irq) > 1) {
412			mTimingDeschedule(&gb->timing, &gb->timer.irq);
413		}
414		if (mTimingUntil(&gb->timing, &gb->timer.irq) == -1) {
415			return;
416		}
417		break;
418	case REG_TMA:
419		if (mTimingUntil(&gb->timing, &gb->timer.irq) == -1) {
420			gb->memory.io[REG_TIMA] = value;
421		}
422		break;
423	case REG_TAC:
424		value = GBTimerUpdateTAC(&gb->timer, value);
425		break;
426	case REG_IF:
427		gb->memory.io[REG_IF] = value | 0xE0;
428		GBUpdateIRQs(gb);
429		return;
430	case REG_LCDC:
431		// TODO: handle GBC differences
432		GBVideoProcessDots(&gb->video, 0);
433		value = gb->video.renderer->writeVideoRegister(gb->video.renderer, address, value);
434		GBVideoWriteLCDC(&gb->video, value);
435		break;
436	case REG_LYC:
437		GBVideoWriteLYC(&gb->video, value);
438		break;
439	case REG_DMA:
440		GBMemoryDMA(gb, value << 8);
441		break;
442	case REG_SCY:
443	case REG_SCX:
444	case REG_WY:
445	case REG_WX:
446		GBVideoProcessDots(&gb->video, 0);
447		value = gb->video.renderer->writeVideoRegister(gb->video.renderer, address, value);
448		break;
449	case REG_BGP:
450	case REG_OBP0:
451	case REG_OBP1:
452		GBVideoProcessDots(&gb->video, 0);
453		GBVideoWritePalette(&gb->video, address, value);
454		break;
455	case REG_STAT:
456		GBVideoWriteSTAT(&gb->video, value);
457		value = gb->video.stat;
458		break;
459	case 0x50:
460		GBUnmapBIOS(gb);
461		if (gb->model >= GB_MODEL_CGB && gb->memory.io[REG_UNK4C] < 0x80) {
462			gb->model = GB_MODEL_DMG;
463			GBVideoDisableCGB(&gb->video);
464		}
465		break;
466	case REG_IE:
467		gb->memory.ie = value;
468		GBUpdateIRQs(gb);
469		return;
470	default:
471		if (gb->model >= GB_MODEL_CGB) {
472			switch (address) {
473			case REG_UNK4C:
474				break;
475			case REG_KEY1:
476				value &= 0x1;
477				value |= gb->memory.io[address] & 0x80;
478				break;
479			case REG_VBK:
480				GBVideoSwitchBank(&gb->video, value);
481				break;
482			case REG_HDMA1:
483			case REG_HDMA2:
484			case REG_HDMA3:
485			case REG_HDMA4:
486				// Handled transparently by the registers
487				break;
488			case REG_HDMA5:
489				value = GBMemoryWriteHDMA5(gb, value);
490				break;
491			case REG_BCPS:
492				gb->video.bcpIndex = value & 0x3F;
493				gb->video.bcpIncrement = value & 0x80;
494				gb->memory.io[REG_BCPD] = gb->video.palette[gb->video.bcpIndex >> 1] >> (8 * (gb->video.bcpIndex & 1));
495				break;
496			case REG_BCPD:
497				if (gb->video.mode != 3) {
498					GBVideoProcessDots(&gb->video, 0);
499					GBVideoWritePalette(&gb->video, address, value);
500				}
501				return;
502			case REG_OCPS:
503				gb->video.ocpIndex = value & 0x3F;
504				gb->video.ocpIncrement = value & 0x80;
505				gb->memory.io[REG_OCPD] = gb->video.palette[8 * 4 + (gb->video.ocpIndex >> 1)] >> (8 * (gb->video.ocpIndex & 1));
506				break;
507			case REG_OCPD:
508				if (gb->video.mode != 3) {
509					GBVideoProcessDots(&gb->video, 0);
510					GBVideoWritePalette(&gb->video, address, value);
511				}
512				return;
513			case REG_SVBK:
514				GBMemorySwitchWramBank(&gb->memory, value);
515				value = gb->memory.wramCurrentBank;
516				break;
517			default:
518				goto failed;
519			}
520			goto success;
521		}
522		failed:
523		mLOG(GB_IO, STUB, "Writing to unknown register FF%02X:%02X", address, value);
524		if (address >= GB_SIZE_IO) {
525			return;
526		}
527		break;
528	}
529	success:
530	gb->memory.io[address] = value;
531}
532
533static uint8_t _readKeys(struct GB* gb) {
534	uint8_t keys = *gb->keySource;
535	if (gb->sgbCurrentController != 0) {
536		keys = 0;
537	}
538	uint8_t joyp = gb->memory.io[REG_JOYP];
539	switch (joyp & 0x30) {
540	case 0x30:
541		keys = gb->sgbCurrentController;
542		break;
543	case 0x20:
544		keys >>= 4;
545		break;
546	case 0x10:
547		break;
548	case 0x00:
549		keys |= keys >> 4;
550		break;
551	}
552	gb->memory.io[REG_JOYP] = (0xCF | joyp) ^ (keys & 0xF);
553	if (joyp & ~gb->memory.io[REG_JOYP] & 0xF) {
554		gb->memory.io[REG_IF] |= (1 << GB_IRQ_KEYPAD);
555		GBUpdateIRQs(gb);
556	}
557	return gb->memory.io[REG_JOYP];
558}
559
560uint8_t GBIORead(struct GB* gb, unsigned address) {
561	switch (address) {
562	case REG_JOYP:
563		return _readKeys(gb);
564	case REG_IE:
565		return gb->memory.ie;
566	case REG_WAVE_0:
567	case REG_WAVE_1:
568	case REG_WAVE_2:
569	case REG_WAVE_3:
570	case REG_WAVE_4:
571	case REG_WAVE_5:
572	case REG_WAVE_6:
573	case REG_WAVE_7:
574	case REG_WAVE_8:
575	case REG_WAVE_9:
576	case REG_WAVE_A:
577	case REG_WAVE_B:
578	case REG_WAVE_C:
579	case REG_WAVE_D:
580	case REG_WAVE_E:
581	case REG_WAVE_F:
582		if (gb->audio.playingCh3) {
583			if (gb->audio.ch3.readable || gb->audio.style != GB_AUDIO_DMG) {
584				return gb->audio.ch3.wavedata8[gb->audio.ch3.window >> 1];
585			} else {
586				return 0xFF;
587			}
588		} else {
589			return gb->audio.ch3.wavedata8[address - REG_WAVE_0];
590		}
591		break;
592	case REG_SB:
593	case REG_SC:
594	case REG_IF:
595	case REG_NR10:
596	case REG_NR11:
597	case REG_NR12:
598	case REG_NR14:
599	case REG_NR21:
600	case REG_NR22:
601	case REG_NR24:
602	case REG_NR30:
603	case REG_NR32:
604	case REG_NR34:
605	case REG_NR41:
606	case REG_NR42:
607	case REG_NR43:
608	case REG_NR44:
609	case REG_NR50:
610	case REG_NR51:
611	case REG_NR52:
612	case REG_DIV:
613	case REG_TIMA:
614	case REG_TMA:
615	case REG_TAC:
616	case REG_STAT:
617	case REG_LCDC:
618	case REG_SCY:
619	case REG_SCX:
620	case REG_LY:
621	case REG_LYC:
622	case REG_DMA:
623	case REG_BGP:
624	case REG_OBP0:
625	case REG_OBP1:
626	case REG_WY:
627	case REG_WX:
628		// Handled transparently by the registers
629		break;
630	default:
631		if (gb->model >= GB_MODEL_CGB) {
632			switch (address) {
633			case REG_KEY1:
634			case REG_VBK:
635			case REG_HDMA1:
636			case REG_HDMA2:
637			case REG_HDMA3:
638			case REG_HDMA4:
639			case REG_HDMA5:
640			case REG_BCPS:
641			case REG_BCPD:
642			case REG_OCPS:
643			case REG_OCPD:
644			case REG_SVBK:
645				// Handled transparently by the registers
646				goto success;
647			default:
648				break;
649			}
650		}
651		mLOG(GB_IO, STUB, "Reading from unknown register FF%02X", address);
652		return 0xFF;
653	}
654	success:
655	return gb->memory.io[address] | _registerMask[address];
656}
657
658void GBTestKeypadIRQ(struct GB* gb) {
659	_readKeys(gb);
660}
661
662struct GBSerializedState;
663void GBIOSerialize(const struct GB* gb, struct GBSerializedState* state) {
664	memcpy(state->io, gb->memory.io, GB_SIZE_IO);
665	state->ie = gb->memory.ie;
666}
667
668void GBIODeserialize(struct GB* gb, const struct GBSerializedState* state) {
669	memcpy(gb->memory.io, state->io, GB_SIZE_IO);
670	gb->memory.ie = state->ie;
671
672	if (GBAudioEnableGetEnable(*gb->audio.nr52)) {
673		GBIOWrite(gb, REG_NR10, gb->memory.io[REG_NR10]);
674		GBIOWrite(gb, REG_NR11, gb->memory.io[REG_NR11]);
675		GBIOWrite(gb, REG_NR12, gb->memory.io[REG_NR12]);
676		GBIOWrite(gb, REG_NR13, gb->memory.io[REG_NR13]);
677		gb->audio.ch1.control.frequency &= 0xFF;
678		gb->audio.ch1.control.frequency |= GBAudioRegisterControlGetFrequency(gb->memory.io[REG_NR14] << 8);
679		gb->audio.ch1.control.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR14] << 8);
680		GBIOWrite(gb, REG_NR21, gb->memory.io[REG_NR21]);
681		GBIOWrite(gb, REG_NR22, gb->memory.io[REG_NR22]);
682		GBIOWrite(gb, REG_NR22, gb->memory.io[REG_NR23]);
683		gb->audio.ch2.control.frequency &= 0xFF;
684		gb->audio.ch2.control.frequency |= GBAudioRegisterControlGetFrequency(gb->memory.io[REG_NR24] << 8);
685		gb->audio.ch2.control.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR24] << 8);
686		GBIOWrite(gb, REG_NR30, gb->memory.io[REG_NR30]);
687		GBIOWrite(gb, REG_NR31, gb->memory.io[REG_NR31]);
688		GBIOWrite(gb, REG_NR32, gb->memory.io[REG_NR32]);
689		GBIOWrite(gb, REG_NR32, gb->memory.io[REG_NR33]);
690		gb->audio.ch3.rate &= 0xFF;
691		gb->audio.ch3.rate |= GBAudioRegisterControlGetRate(gb->memory.io[REG_NR34] << 8);
692		gb->audio.ch3.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR34] << 8);
693		GBIOWrite(gb, REG_NR41, gb->memory.io[REG_NR41]);
694		GBIOWrite(gb, REG_NR42, gb->memory.io[REG_NR42]);
695		GBIOWrite(gb, REG_NR43, gb->memory.io[REG_NR43]);
696		gb->audio.ch4.stop = GBAudioRegisterNoiseControlGetStop(gb->memory.io[REG_NR44]);
697		GBIOWrite(gb, REG_NR50, gb->memory.io[REG_NR50]);
698		GBIOWrite(gb, REG_NR51, gb->memory.io[REG_NR51]);
699	}
700
701	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_LCDC, state->io[REG_LCDC]);
702	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_SCY, state->io[REG_SCY]);
703	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_SCX, state->io[REG_SCX]);
704	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_WY, state->io[REG_WY]);
705	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_WX, state->io[REG_WX]);
706	if (gb->model == GB_MODEL_SGB) {
707		gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_BGP, state->io[REG_BGP]);
708		gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_OBP0, state->io[REG_OBP0]);
709		gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_OBP1, state->io[REG_OBP1]);
710	}
711	gb->video.stat = state->io[REG_STAT];
712}