all repos — mgba @ 773151638842e8a91cf0f4b2661322719fc3abb9

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