all repos — mgba @ c2490afe4f5e7c3c7ab8eb112935e097945e7ae6

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_BGP, 0xFC);
194	if (gb->model < GB_MODEL_CGB) {
195		GBIOWrite(gb, REG_OBP0, 0xFF);
196		GBIOWrite(gb, REG_OBP1, 0xFF);
197	}
198	GBIOWrite(gb, REG_WY, 0x00);
199	GBIOWrite(gb, REG_WX, 0x00);
200	if (gb->model >= GB_MODEL_CGB) {
201		GBIOWrite(gb, REG_UNK4C, 0);
202		GBIOWrite(gb, REG_JOYP, 0xFF);
203		GBIOWrite(gb, REG_VBK, 0);
204		GBIOWrite(gb, REG_BCPS, 0);
205		GBIOWrite(gb, REG_OCPS, 0);
206		GBIOWrite(gb, REG_SVBK, 1);
207		GBIOWrite(gb, REG_HDMA1, 0xFF);
208		GBIOWrite(gb, REG_HDMA2, 0xFF);
209		GBIOWrite(gb, REG_HDMA3, 0xFF);
210		GBIOWrite(gb, REG_HDMA4, 0xFF);
211		gb->memory.io[REG_HDMA5] = 0xFF;
212	} else if (gb->model == GB_MODEL_SGB) {
213		GBIOWrite(gb, REG_JOYP, 0xFF);
214	}
215	GBIOWrite(gb, REG_IE, 0x00);
216}
217
218void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
219	switch (address) {
220	case REG_SB:
221		GBSIOWriteSB(&gb->sio, value);
222		break;
223	case REG_SC:
224		GBSIOWriteSC(&gb->sio, value);
225		break;
226	case REG_DIV:
227		GBTimerDivReset(&gb->timer);
228		return;
229	case REG_NR10:
230		if (gb->audio.enable) {
231			GBAudioWriteNR10(&gb->audio, value);
232		} else {
233			value = 0;
234		}
235		break;
236	case REG_NR11:
237		if (gb->audio.enable) {
238			GBAudioWriteNR11(&gb->audio, value);
239		} else {
240			if (gb->audio.style == GB_AUDIO_DMG) {
241				GBAudioWriteNR11(&gb->audio, value & _registerMask[REG_NR11]);
242			}
243			value = 0;
244		}
245		break;
246	case REG_NR12:
247		if (gb->audio.enable) {
248			GBAudioWriteNR12(&gb->audio, value);
249		} else {
250			value = 0;
251		}
252		break;
253	case REG_NR13:
254		if (gb->audio.enable) {
255			GBAudioWriteNR13(&gb->audio, value);
256		} else {
257			value = 0;
258		}
259		break;
260	case REG_NR14:
261		if (gb->audio.enable) {
262			GBAudioWriteNR14(&gb->audio, value);
263		} else {
264			value = 0;
265		}
266		break;
267	case REG_NR21:
268		if (gb->audio.enable) {
269			GBAudioWriteNR21(&gb->audio, value);
270		} else {
271			if (gb->audio.style == GB_AUDIO_DMG) {
272				GBAudioWriteNR21(&gb->audio, value & _registerMask[REG_NR21]);
273			}
274			value = 0;
275		}
276		break;
277	case REG_NR22:
278		if (gb->audio.enable) {
279			GBAudioWriteNR22(&gb->audio, value);
280		} else {
281			value = 0;
282		}
283		break;
284	case REG_NR23:
285		if (gb->audio.enable) {
286			GBAudioWriteNR23(&gb->audio, value);
287		} else {
288			value = 0;
289		}
290		break;
291	case REG_NR24:
292		if (gb->audio.enable) {
293			GBAudioWriteNR24(&gb->audio, value);
294		} else {
295			value = 0;
296		}
297		break;
298	case REG_NR30:
299		if (gb->audio.enable) {
300			GBAudioWriteNR30(&gb->audio, value);
301		} else {
302			value = 0;
303		}
304		break;
305	case REG_NR31:
306		if (gb->audio.enable || gb->audio.style == GB_AUDIO_DMG) {
307			GBAudioWriteNR31(&gb->audio, value);
308		} else {
309			value = 0;
310		}
311		break;
312	case REG_NR32:
313		if (gb->audio.enable) {
314			GBAudioWriteNR32(&gb->audio, value);
315		} else {
316			value = 0;
317		}
318		break;
319	case REG_NR33:
320		if (gb->audio.enable) {
321			GBAudioWriteNR33(&gb->audio, value);
322		} else {
323			value = 0;
324		}
325		break;
326	case REG_NR34:
327		if (gb->audio.enable) {
328			GBAudioWriteNR34(&gb->audio, value);
329		} else {
330			value = 0;
331		}
332		break;
333	case REG_NR41:
334		if (gb->audio.enable || gb->audio.style == GB_AUDIO_DMG) {
335			GBAudioWriteNR41(&gb->audio, value);
336		} else {
337			value = 0;
338		}
339		break;
340	case REG_NR42:
341		if (gb->audio.enable) {
342			GBAudioWriteNR42(&gb->audio, value);
343		} else {
344			value = 0;
345		}
346		break;
347	case REG_NR43:
348		if (gb->audio.enable) {
349			GBAudioWriteNR43(&gb->audio, value);
350		} else {
351			value = 0;
352		}
353		break;
354	case REG_NR44:
355		if (gb->audio.enable) {
356			GBAudioWriteNR44(&gb->audio, value);
357		} else {
358			value = 0;
359		}
360		break;
361	case REG_NR50:
362		if (gb->audio.enable) {
363			GBAudioWriteNR50(&gb->audio, value);
364		} else {
365			value = 0;
366		}
367		break;
368	case REG_NR51:
369		if (gb->audio.enable) {
370			GBAudioWriteNR51(&gb->audio, value);
371		} else {
372			value = 0;
373		}
374		break;
375	case REG_NR52:
376		GBAudioWriteNR52(&gb->audio, value);
377		value &= 0x80;
378		value |= gb->memory.io[REG_NR52] & 0x0F;
379		break;
380	case REG_WAVE_0:
381	case REG_WAVE_1:
382	case REG_WAVE_2:
383	case REG_WAVE_3:
384	case REG_WAVE_4:
385	case REG_WAVE_5:
386	case REG_WAVE_6:
387	case REG_WAVE_7:
388	case REG_WAVE_8:
389	case REG_WAVE_9:
390	case REG_WAVE_A:
391	case REG_WAVE_B:
392	case REG_WAVE_C:
393	case REG_WAVE_D:
394	case REG_WAVE_E:
395	case REG_WAVE_F:
396		if (!gb->audio.playingCh3 || gb->audio.style != GB_AUDIO_DMG) {
397			gb->audio.ch3.wavedata8[address - REG_WAVE_0] = value;
398		} else if(gb->audio.ch3.readable) {
399			gb->audio.ch3.wavedata8[gb->audio.ch3.window >> 1] = value;
400		}
401		break;
402	case REG_JOYP:
403		gb->memory.io[REG_JOYP] = value | 0x0F;
404		_readKeys(gb);
405		if (gb->model == GB_MODEL_SGB) {
406			_writeSGBBits(gb, (value >> 4) & 3);
407		}
408		return;
409	case REG_TIMA:
410		if (value && mTimingUntil(&gb->timing, &gb->timer.irq) > 1) {
411			mTimingDeschedule(&gb->timing, &gb->timer.irq);
412		}
413		if (mTimingUntil(&gb->timing, &gb->timer.irq) == -1) {
414			return;
415		}
416		break;
417	case REG_TMA:
418		if (mTimingUntil(&gb->timing, &gb->timer.irq) == -1) {
419			gb->memory.io[REG_TIMA] = value;
420		}
421		break;
422	case REG_TAC:
423		value = GBTimerUpdateTAC(&gb->timer, value);
424		break;
425	case REG_IF:
426		gb->memory.io[REG_IF] = value | 0xE0;
427		GBUpdateIRQs(gb);
428		return;
429	case REG_LCDC:
430		// TODO: handle GBC differences
431		GBVideoProcessDots(&gb->video, 0);
432		value = gb->video.renderer->writeVideoRegister(gb->video.renderer, address, value);
433		GBVideoWriteLCDC(&gb->video, value);
434		break;
435	case REG_LYC:
436		GBVideoWriteLYC(&gb->video, value);
437		break;
438	case REG_DMA:
439		GBMemoryDMA(gb, value << 8);
440		break;
441	case REG_SCY:
442	case REG_SCX:
443	case REG_WY:
444	case REG_WX:
445		GBVideoProcessDots(&gb->video, 0);
446		value = gb->video.renderer->writeVideoRegister(gb->video.renderer, address, value);
447		break;
448	case REG_BGP:
449	case REG_OBP0:
450	case REG_OBP1:
451		GBVideoProcessDots(&gb->video, 0);
452		GBVideoWritePalette(&gb->video, address, value);
453		break;
454	case REG_STAT:
455		GBVideoWriteSTAT(&gb->video, value);
456		value = gb->video.stat;
457		break;
458	case 0x50:
459		GBUnmapBIOS(gb);
460		if (gb->model >= GB_MODEL_CGB && gb->memory.io[REG_UNK4C] < 0x80) {
461			gb->model = GB_MODEL_DMG;
462			GBVideoDisableCGB(&gb->video);
463		}
464		break;
465	case REG_IE:
466		gb->memory.ie = value;
467		GBUpdateIRQs(gb);
468		return;
469	default:
470		if (gb->model >= GB_MODEL_CGB) {
471			switch (address) {
472			case REG_UNK4C:
473				break;
474			case REG_KEY1:
475				value &= 0x1;
476				value |= gb->memory.io[address] & 0x80;
477				break;
478			case REG_VBK:
479				GBVideoSwitchBank(&gb->video, value);
480				break;
481			case REG_HDMA1:
482			case REG_HDMA2:
483			case REG_HDMA3:
484			case REG_HDMA4:
485				// Handled transparently by the registers
486				break;
487			case REG_HDMA5:
488				value = GBMemoryWriteHDMA5(gb, value);
489				break;
490			case REG_BCPS:
491				gb->video.bcpIndex = value & 0x3F;
492				gb->video.bcpIncrement = value & 0x80;
493				gb->memory.io[REG_BCPD] = gb->video.palette[gb->video.bcpIndex >> 1] >> (8 * (gb->video.bcpIndex & 1));
494				break;
495			case REG_BCPD:
496				if (gb->video.mode != 3) {
497					GBVideoProcessDots(&gb->video, 0);
498					GBVideoWritePalette(&gb->video, address, value);
499				}
500				return;
501			case REG_OCPS:
502				gb->video.ocpIndex = value & 0x3F;
503				gb->video.ocpIncrement = value & 0x80;
504				gb->memory.io[REG_OCPD] = gb->video.palette[8 * 4 + (gb->video.ocpIndex >> 1)] >> (8 * (gb->video.ocpIndex & 1));
505				break;
506			case REG_OCPD:
507				if (gb->video.mode != 3) {
508					GBVideoProcessDots(&gb->video, 0);
509					GBVideoWritePalette(&gb->video, address, value);
510				}
511				return;
512			case REG_SVBK:
513				GBMemorySwitchWramBank(&gb->memory, value);
514				value = gb->memory.wramCurrentBank;
515				break;
516			default:
517				goto failed;
518			}
519			goto success;
520		}
521		failed:
522		mLOG(GB_IO, STUB, "Writing to unknown register FF%02X:%02X", address, value);
523		if (address >= GB_SIZE_IO) {
524			return;
525		}
526		break;
527	}
528	success:
529	gb->memory.io[address] = value;
530}
531
532static uint8_t _readKeys(struct GB* gb) {
533	uint8_t keys = *gb->keySource;
534	if (gb->sgbCurrentController != 0) {
535		keys = 0;
536	}
537	uint8_t joyp = gb->memory.io[REG_JOYP];
538	switch (joyp & 0x30) {
539	case 0x30:
540		keys = gb->sgbCurrentController;
541		break;
542	case 0x20:
543		keys >>= 4;
544		break;
545	case 0x10:
546		break;
547	case 0x00:
548		keys |= keys >> 4;
549		break;
550	}
551	gb->memory.io[REG_JOYP] = (0xCF | joyp) ^ (keys & 0xF);
552	if (joyp & ~gb->memory.io[REG_JOYP] & 0xF) {
553		gb->memory.io[REG_IF] |= (1 << GB_IRQ_KEYPAD);
554		GBUpdateIRQs(gb);
555	}
556	return gb->memory.io[REG_JOYP];
557}
558
559uint8_t GBIORead(struct GB* gb, unsigned address) {
560	switch (address) {
561	case REG_JOYP:
562		return _readKeys(gb);
563	case REG_IE:
564		return gb->memory.ie;
565	case REG_WAVE_0:
566	case REG_WAVE_1:
567	case REG_WAVE_2:
568	case REG_WAVE_3:
569	case REG_WAVE_4:
570	case REG_WAVE_5:
571	case REG_WAVE_6:
572	case REG_WAVE_7:
573	case REG_WAVE_8:
574	case REG_WAVE_9:
575	case REG_WAVE_A:
576	case REG_WAVE_B:
577	case REG_WAVE_C:
578	case REG_WAVE_D:
579	case REG_WAVE_E:
580	case REG_WAVE_F:
581		if (gb->audio.playingCh3) {
582			if (gb->audio.ch3.readable || gb->audio.style != GB_AUDIO_DMG) {
583				return gb->audio.ch3.wavedata8[gb->audio.ch3.window >> 1];
584			} else {
585				return 0xFF;
586			}
587		} else {
588			return gb->audio.ch3.wavedata8[address - REG_WAVE_0];
589		}
590		break;
591	case REG_SB:
592	case REG_SC:
593	case REG_IF:
594	case REG_NR10:
595	case REG_NR11:
596	case REG_NR12:
597	case REG_NR14:
598	case REG_NR21:
599	case REG_NR22:
600	case REG_NR24:
601	case REG_NR30:
602	case REG_NR32:
603	case REG_NR34:
604	case REG_NR41:
605	case REG_NR42:
606	case REG_NR43:
607	case REG_NR44:
608	case REG_NR50:
609	case REG_NR51:
610	case REG_NR52:
611	case REG_DIV:
612	case REG_TIMA:
613	case REG_TMA:
614	case REG_TAC:
615	case REG_STAT:
616	case REG_LCDC:
617	case REG_SCY:
618	case REG_SCX:
619	case REG_LY:
620	case REG_LYC:
621	case REG_BGP:
622	case REG_OBP0:
623	case REG_OBP1:
624	case REG_WY:
625	case REG_WX:
626		// Handled transparently by the registers
627		break;
628	default:
629		if (gb->model >= GB_MODEL_CGB) {
630			switch (address) {
631			case REG_KEY1:
632			case REG_VBK:
633			case REG_HDMA1:
634			case REG_HDMA2:
635			case REG_HDMA3:
636			case REG_HDMA4:
637			case REG_HDMA5:
638			case REG_BCPS:
639			case REG_BCPD:
640			case REG_OCPS:
641			case REG_OCPD:
642			case REG_SVBK:
643				// Handled transparently by the registers
644				goto success;
645			case REG_DMA:
646				mLOG(GB_IO, STUB, "Reading from unknown register FF%02X", address);
647				return 0;
648			default:
649				break;
650			}
651		}
652		mLOG(GB_IO, STUB, "Reading from unknown register FF%02X", address);
653		return 0xFF;
654	}
655	success:
656	return gb->memory.io[address] | _registerMask[address];
657}
658
659void GBTestKeypadIRQ(struct GB* gb) {
660	_readKeys(gb);
661}
662
663struct GBSerializedState;
664void GBIOSerialize(const struct GB* gb, struct GBSerializedState* state) {
665	memcpy(state->io, gb->memory.io, GB_SIZE_IO);
666	state->ie = gb->memory.ie;
667}
668
669void GBIODeserialize(struct GB* gb, const struct GBSerializedState* state) {
670	memcpy(gb->memory.io, state->io, GB_SIZE_IO);
671	gb->memory.ie = state->ie;
672
673	if (GBAudioEnableGetEnable(*gb->audio.nr52)) {
674		GBIOWrite(gb, REG_NR10, gb->memory.io[REG_NR10]);
675		GBIOWrite(gb, REG_NR11, gb->memory.io[REG_NR11]);
676		GBIOWrite(gb, REG_NR12, gb->memory.io[REG_NR12]);
677		GBIOWrite(gb, REG_NR13, gb->memory.io[REG_NR13]);
678		gb->audio.ch1.control.frequency &= 0xFF;
679		gb->audio.ch1.control.frequency |= GBAudioRegisterControlGetFrequency(gb->memory.io[REG_NR14] << 8);
680		gb->audio.ch1.control.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR14] << 8);
681		GBIOWrite(gb, REG_NR21, gb->memory.io[REG_NR21]);
682		GBIOWrite(gb, REG_NR22, gb->memory.io[REG_NR22]);
683		GBIOWrite(gb, REG_NR22, gb->memory.io[REG_NR23]);
684		gb->audio.ch2.control.frequency &= 0xFF;
685		gb->audio.ch2.control.frequency |= GBAudioRegisterControlGetFrequency(gb->memory.io[REG_NR24] << 8);
686		gb->audio.ch2.control.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR24] << 8);
687		GBIOWrite(gb, REG_NR30, gb->memory.io[REG_NR30]);
688		GBIOWrite(gb, REG_NR31, gb->memory.io[REG_NR31]);
689		GBIOWrite(gb, REG_NR32, gb->memory.io[REG_NR32]);
690		GBIOWrite(gb, REG_NR32, gb->memory.io[REG_NR33]);
691		gb->audio.ch3.rate &= 0xFF;
692		gb->audio.ch3.rate |= GBAudioRegisterControlGetRate(gb->memory.io[REG_NR34] << 8);
693		gb->audio.ch3.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR34] << 8);
694		GBIOWrite(gb, REG_NR41, gb->memory.io[REG_NR41]);
695		GBIOWrite(gb, REG_NR42, gb->memory.io[REG_NR42]);
696		GBIOWrite(gb, REG_NR43, gb->memory.io[REG_NR43]);
697		gb->audio.ch4.stop = GBAudioRegisterNoiseControlGetStop(gb->memory.io[REG_NR44]);
698		GBIOWrite(gb, REG_NR50, gb->memory.io[REG_NR50]);
699		GBIOWrite(gb, REG_NR51, gb->memory.io[REG_NR51]);
700	}
701
702	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_LCDC, state->io[REG_LCDC]);
703	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_SCY, state->io[REG_SCY]);
704	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_SCX, state->io[REG_SCX]);
705	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_WY, state->io[REG_WY]);
706	gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_WX, state->io[REG_WX]);
707	if (gb->model == GB_MODEL_SGB) {
708		gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_BGP, state->io[REG_BGP]);
709		gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_OBP0, state->io[REG_OBP0]);
710		gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_OBP1, state->io[REG_OBP1]);
711	}
712	gb->video.stat = state->io[REG_STAT];
713}