public void UpdateStatus(GbState state) { _lastState = state; _cpuBinder.Entity = state.Cpu; _cpuBinder.UpdateUI(); txtHL.Text = ((state.Cpu.H << 8) | state.Cpu.L).ToString("X4"); _ppuBinder.Entity = state.Ppu; _ppuBinder.UpdateUI(); UpdateCpuFlags(); UpdateStack(); }
public static byte[] GetGameboyPalette() { byte[] cgRam = new byte[512]; //Generate a fake SNES-like palette based on the gameboy PPU state GbState state = DebugApi.GetState().Gameboy; GbPpuState ppu = state.Ppu; if (state.Type == GbType.Cgb) { for (int i = 0; i < 8 * 4; i++) { cgRam[i * 2] = (byte)(ppu.CgbBgPalettes[i] & 0xFF); cgRam[i * 2 + 1] = (byte)(ppu.CgbBgPalettes[i] >> 8); } for (int i = 0; i < 8 * 4; i++) { cgRam[128 + i * 2] = (byte)(ppu.CgbObjPalettes[i] & 0xFF); cgRam[128 + i * 2 + 1] = (byte)(ppu.CgbObjPalettes[i] >> 8); } } else { byte[,] paletteBytes = new byte[4, 2] { { 0xFF, 0x7F }, { 0x18, 0x63 }, { 0x8C, 0x31 }, { 0, 0 } }; Action <byte, UInt16> setPalette = (byte pal, UInt16 offset) => { cgRam[offset] = paletteBytes[pal & 0x03, 0]; cgRam[offset + 1] = paletteBytes[pal & 0x03, 1]; cgRam[offset + 2] = paletteBytes[(pal >> 2) & 0x03, 0]; cgRam[offset + 3] = paletteBytes[(pal >> 2) & 0x03, 1]; cgRam[offset + 4] = paletteBytes[(pal >> 4) & 0x03, 0]; cgRam[offset + 5] = paletteBytes[(pal >> 4) & 0x03, 1]; cgRam[offset + 6] = paletteBytes[(pal >> 6) & 0x03, 0]; cgRam[offset + 7] = paletteBytes[(pal >> 6) & 0x03, 1]; }; setPalette(ppu.BgPalette, 0); setPalette(ppu.ObjPalette0, 32); setPalette(ppu.ObjPalette1, 64); setPalette(0xE4, 96); } return(cgRam); }
private void UpdateGameboyTab() { GbState gb = _state.Gameboy; List <RegEntry> entries = new List <RegEntry>(); GbPpuState ppu = gb.Ppu; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF40", "LCD Control (LCDC)", null), new RegEntry("$FF40.0", "Background Enabled", ppu.BgEnabled), new RegEntry("$FF40.1", "Sprites Enabled", ppu.BgEnabled), new RegEntry("$FF40.2", "Sprite size", ppu.LargeSprites ? "8x16" : "8x8"), new RegEntry("$FF40.3", "BG Tilemap Select", ppu.BgTilemapSelect ? 0x9C00 : 0x9800, Format.X16), new RegEntry("$FF40.4", "BG Tile Select", ppu.BgTileSelect ? "$8000-$8FFF" : "$8800-$97FF"), new RegEntry("$FF40.5", "Window Enabled", ppu.WindowEnabled), new RegEntry("$FF40.6", "Window Tilemap Select", ppu.WindowTilemapSelect ? 0x9C00 : 0x9800, Format.X16), new RegEntry("$FF40.7", "LCD Enabled", ppu.LcdEnabled), new RegEntry("$FF41", "LCD Status (STAT)", null), new RegEntry("$FF41.0-1", "Mode", (int)ppu.Mode), new RegEntry("$FF41.2", "Coincidence Flag", ppu.LyCoincidenceFlag), new RegEntry("$FF41.3", "Mode 0 H-Blank IRQ", (ppu.Status & 0x08) != 0), new RegEntry("$FF41.4", "Mode 1 V-Blank IRQ", (ppu.Status & 0x10) != 0), new RegEntry("$FF41.5", "Mode 2 OAM IRQ", (ppu.Status & 0x20) != 0), new RegEntry("$FF41.6", "LYC=LY Coincidence IRQ", (ppu.Status & 0x40) != 0), new RegEntry("", "LCD Registers", null), new RegEntry("$FF42", "Scroll Y (SCY)", ppu.ScrollY, Format.X8), new RegEntry("$FF43", "Scroll X (SCX)", ppu.ScrollX, Format.X8), new RegEntry("$FF44", "Y-Coordinate (LY)", ppu.Ly, Format.X8), new RegEntry("$FF45", "LY Compare (LYC)", ppu.LyCompare, Format.X8), new RegEntry("$FF47", "BG Palette (BGP)", ppu.BgPalette, Format.X8), new RegEntry("$FF48", "OBJ Palette 0 (OBP0)", ppu.ObjPalette0, Format.X8), new RegEntry("$FF49", "OBJ Palette 1 (OBP1)", ppu.ObjPalette1, Format.X8), new RegEntry("$FF4A", "Window Y (WY)", ppu.WindowY, Format.X8), new RegEntry("$FF4B", "Window X (WX)", ppu.WindowX, Format.X8), }); GbTimerState timer = gb.Timer; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF04-7", "Timer", null), new RegEntry("$FF04", "DIV - Divider", timer.Divider, Format.X16), new RegEntry("$FF05", "TIMA - Counter", timer.Counter, Format.X8), new RegEntry("$FF06", "TMA - Modulo", timer.Modulo, Format.X8), new RegEntry("$FF07", "TAC - Control", timer.Control, Format.X8) }); GbDmaControllerState dma = gb.Dma; entries.AddRange(new List <RegEntry>() { new RegEntry("", "DMA", null), new RegEntry("$FF46", "OAM DMA - Source", (dma.OamDmaSource << 8), Format.X16), new RegEntry("$FF51-2", "CGB - Source", dma.CgbDmaSource, Format.X16), new RegEntry("$FF53-4", "CGB - Destination", dma.CgbDmaDest, Format.X16), new RegEntry("$FF55.0-6", "CGB - Length", dma.CgbDmaLength, Format.X8), new RegEntry("$FF55.7", "CGB - HDMA Done", dma.CgbHdmaDone), new RegEntry("", "CGB - HDMA Running", dma.CgbHdmaRunning), }); GbMemoryManagerState memManager = gb.MemoryManager; entries.AddRange(new List <RegEntry>() { new RegEntry("", "IRQ", null), new RegEntry("$FF0F", "IF - IRQ Flags", memManager.IrqRequests, Format.X8), new RegEntry("$FF0F.0", "IF - Vertical Blank IRQ", (memManager.IrqRequests & 0x01) != 0), new RegEntry("$FF0F.1", "IF - STAT IRQ", (memManager.IrqRequests & 0x02) != 0), new RegEntry("$FF0F.2", "IF - Timer IRQ", (memManager.IrqRequests & 0x04) != 0), new RegEntry("$FF0F.3", "IF - Serial IRQ", (memManager.IrqRequests & 0x08) != 0), new RegEntry("$FF0F.4", "IF - Joypad IRQ", (memManager.IrqRequests & 0x10) != 0), new RegEntry("$FFFF", "IE - IRQ Enabled", memManager.IrqEnabled, Format.X8), new RegEntry("$FFFF.0", "IE - Vertical Blank IRQ Enabled", (memManager.IrqEnabled & 0x01) != 0), new RegEntry("$FFFF.1", "IE - STAT IRQ Enabled", (memManager.IrqEnabled & 0x02) != 0), new RegEntry("$FFFF.2", "IE - Timer IRQ Enabled", (memManager.IrqEnabled & 0x04) != 0), new RegEntry("$FFFF.3", "IE - Serial IRQ Enabled", (memManager.IrqEnabled & 0x08) != 0), new RegEntry("$FFFF.4", "IE - Joypad IRQ Enabled", (memManager.IrqEnabled & 0x10) != 0), new RegEntry("", "Misc", null), new RegEntry("$FF00", "Input Select", memManager.InputSelect, Format.X8), new RegEntry("$FF01", "Serial Data", memManager.SerialData, Format.X8), new RegEntry("$FF02", "Serial Control", memManager.SerialControl, Format.X8), new RegEntry("", "Serial Bit Count", memManager.SerialBitCount), }); GbApuState apu = gb.Apu.Common; entries.AddRange(new List <RegEntry>() { new RegEntry("", "APU", null), new RegEntry("$FF24.0-2", "Volume Right", apu.RightVolume), new RegEntry("$FF24.3", "External Audio Right Enabled", apu.ExtAudioRightEnabled), new RegEntry("$FF24.4-6", "Volume Left", apu.LeftVolume), new RegEntry("$FF24.7", "External Audio Left Enabled", apu.ExtAudioRightEnabled), new RegEntry("$FF25.0", "Right Square 1 Enabled", apu.EnableRightSq1 != 0), new RegEntry("$FF25.1", "Right Square 2 Enabled", apu.EnableRightSq2 != 0), new RegEntry("$FF25.2", "Right Wave Enabled", apu.EnableRightWave != 0), new RegEntry("$FF25.3", "Right Noise Enabled", apu.EnableRightNoise != 0), new RegEntry("$FF25.4", "Left Square 1 Enabled", apu.EnableLeftSq1 != 0), new RegEntry("$FF25.5", "Left Square 2 Enabled", apu.EnableLeftSq2 != 0), new RegEntry("$FF25.6", "Left Wave Enabled", apu.EnableLeftWave != 0), new RegEntry("$FF25.7", "Left Noise Enabled", apu.EnableLeftNoise != 0), new RegEntry("$FF26.7", "APU Enabled", apu.ApuEnabled), new RegEntry("", "Frame Sequencer", apu.FrameSequenceStep), }); GbSquareState sq1 = gb.Apu.Square1; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF10-$FF14", "Square 1", null), new RegEntry("$FF10.0-2", "Sweep Shift", sq1.SweepShift), new RegEntry("$FF10.3", "Sweep Negate", sq1.SweepNegate), new RegEntry("$FF10.4-7", "Sweep Period", sq1.SweepPeriod), new RegEntry("$FF11.0-5", "Length", sq1.Length), new RegEntry("$FF11.6-7", "Duty", sq1.Duty), new RegEntry("$FF12.0-2", "Envelope Period", sq1.EnvPeriod), new RegEntry("$FF12.3", "Envelope Increase Volume", sq1.EnvRaiseVolume), new RegEntry("$FF12.4-7", "Envelope Volume", sq1.EnvVolume), new RegEntry("$FF13+$FF14.0-2", "Frequency", sq1.Frequency), new RegEntry("$FF14.6", "Length Counter Enabled", sq1.LengthEnabled), new RegEntry("$FF14.7", "Channel Enabled", sq1.Enabled), new RegEntry("--", "Timer", sq1.Timer), new RegEntry("--", "Duty Position", sq1.DutyPos), new RegEntry("--", "Sweep Enabled", sq1.SweepEnabled), new RegEntry("--", "Sweep Frequency", sq1.SweepFreq), new RegEntry("--", "Sweep Timer", sq1.SweepTimer), new RegEntry("--", "Envelope Timer", sq1.EnvTimer), new RegEntry("--", "Output", sq1.Output) }); GbSquareState sq2 = gb.Apu.Square2; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF16-$FF19", "Square 2", null), new RegEntry("$FF16.0-5", "Length", sq2.Length), new RegEntry("$FF16.6-7", "Duty", sq2.Duty), new RegEntry("$FF17.0-2", "Envelope Period", sq2.EnvPeriod), new RegEntry("$FF17.3", "Envelope Increase Volume", sq2.EnvRaiseVolume), new RegEntry("$FF17.4-7", "Envelope Volume", sq2.EnvVolume), new RegEntry("$FF18+$FF19.0-2", "Frequency", sq2.Frequency), new RegEntry("$FF19.6", "Length Counter Enabled", sq2.LengthEnabled), new RegEntry("$FF19.7", "Channel Enabled", sq2.Enabled), new RegEntry("--", "Timer", sq2.Timer), new RegEntry("--", "Duty Position", sq2.DutyPos), new RegEntry("--", "Envelope Timer", sq2.EnvTimer), new RegEntry("--", "Output", sq2.Output) }); GbNoiseState noise = gb.Apu.Noise; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF20-$FF23", "Noise", null), new RegEntry("$FF20.0-5", "Length", noise.Length), new RegEntry("$FF21.0-2", "Envelope Period", noise.EnvPeriod), new RegEntry("$FF21.3", "Envelope Increase Volume", noise.EnvRaiseVolume), new RegEntry("$FF21.4-7", "Envelope Volume", noise.EnvVolume), new RegEntry("$FF23.0-2", "Divisor", noise.Divisor), new RegEntry("$FF23.3", "Short Mode", noise.ShortWidthMode), new RegEntry("$FF23.4-7", "Period Shift", noise.PeriodShift), new RegEntry("$FF24.6", "Length Counter Enabled", noise.LengthEnabled), new RegEntry("$FF24.7", "Channel Enabled", noise.Enabled), new RegEntry("--", "Timer", noise.Timer), new RegEntry("--", "Envelope Timer", noise.EnvTimer), new RegEntry("--", "Shift Register", noise.ShiftRegister, Format.X16), new RegEntry("--", "Output", noise.Output) }); GbWaveState wave = gb.Apu.Wave; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF1A-$FF1E", "Wave", null), new RegEntry("$FF1A.7", "Sound Enabled", wave.DacEnabled), new RegEntry("$FF1B", "Length", wave.Length), new RegEntry("$FF1C.5-6", "Volume", wave.Volume), new RegEntry("$FF1D+$FF1E.0-2", "Frequency", wave.Frequency), new RegEntry("$FF1E.6", "Length Counter Enabled", wave.LengthEnabled), new RegEntry("$FF1E.7", "Channel Enabled", wave.Enabled), new RegEntry("--", "Timer", wave.Timer), new RegEntry("--", "Sample Buffer", wave.SampleBuffer), new RegEntry("--", "Position", wave.Position), new RegEntry("--", "Output", wave.Output), }); ctrlCoprocessor.UpdateState(entries); }
public void UpdateCpuRegions(GbState gbState) { GbMemoryManagerState state = gbState.MemoryManager; List <MemoryRegionInfo> regions = new List <MemoryRegionInfo>(); Action <int> addEmpty = (int size) => { regions.Add(new MemoryRegionInfo() { Name = "N/A", Size = size, Color = Color.FromArgb(222, 222, 222) }); }; Action <int, int, RegisterAccess> addWorkRam = (int page, int size, RegisterAccess type) => { string name = size >= 0x1000 ? ("WRAM ($" + page.ToString("X2") + ")") : (size >= 0x800 ? ("$" + page.ToString("X2")) : ""); regions.Add(new MemoryRegionInfo() { Name = name, Size = size, Color = Color.FromArgb(0xCD, 0xDC, 0xFA), AccessType = type }); }; Action <int, int, RegisterAccess> addSaveRam = (int page, int size, RegisterAccess type) => { string name = size >= 0x2000 ? ("Save RAM ($" + page.ToString("X2") + ")") : (size >= 0x800 ? ("$" + page.ToString("X2")) : ""); regions.Add(new MemoryRegionInfo() { Name = name, Size = size, Color = Color.FromArgb(0xFA, 0xDC, 0xCD), AccessType = type }); }; Action <int, int, RegisterAccess> addCartRam = (int page, int size, RegisterAccess type) => { string name = size >= 0x2000 ? ("Cart RAM ($" + page.ToString("X2") + ")") : (size >= 0x800 ? ("$" + page.ToString("X2")) : ""); regions.Add(new MemoryRegionInfo() { Name = name, Size = size, Color = Color.FromArgb(0xFA, 0xDC, 0xCD), AccessType = type }); }; Action <int, int, Color> addPrgRom = (int page, int size, Color color) => { regions.Add(new MemoryRegionInfo() { Name = "$" + page.ToString("X2"), Size = size, Color = color }); }; Action <int> addBootRom = (int size) => { regions.Add(new MemoryRegionInfo() { Name = "", Size = size, Color = Color.IndianRed }); }; GbMemoryType memoryType = GbMemoryType.None; RegisterAccess accessType = RegisterAccess.None; int currentSize = 0; int startIndex = 0; bool alternateColor = true; const int prgBankSize = 0x4000; const int otherBankSize = 0x2000; Action <int> addSection = (int i) => { if (currentSize == 0) { return; } if (memoryType == GbMemoryType.None) { addEmpty(currentSize); } else if (memoryType == GbMemoryType.PrgRom) { addPrgRom((int)(state.MemoryOffset[startIndex] / prgBankSize), currentSize, alternateColor ? Color.FromArgb(0xC4, 0xE7, 0xD4) : Color.FromArgb(0xA4, 0xD7, 0xB4)); alternateColor = !alternateColor; } else if (memoryType == GbMemoryType.WorkRam) { addWorkRam((int)(state.MemoryOffset[startIndex] / otherBankSize), currentSize, accessType); } else if (memoryType == GbMemoryType.CartRam) { if (gbState.HasBattery) { addSaveRam((int)(state.MemoryOffset[startIndex] / otherBankSize), currentSize, accessType); } else { addCartRam((int)(state.MemoryOffset[startIndex] / otherBankSize), currentSize, accessType); } } else if (memoryType == GbMemoryType.BootRom) { addBootRom(currentSize); } currentSize = 0; startIndex = i; }; for (int i = 0; i < 0xFE; i++) { if (i == 0x80) { addSection(i); regions.Add(new MemoryRegionInfo() { Name = "VRAM", Size = 0x2000, Color = Color.FromArgb(0xFA, 0xDC, 0xCD), AccessType = RegisterAccess.ReadWrite }); addSection(i); memoryType = GbMemoryType.None; accessType = RegisterAccess.None; currentSize = 0; i += 0x20; } if (state.MemoryAccessType[i] != RegisterAccess.None) { bool forceNewBlock = ( (memoryType == GbMemoryType.PrgRom && state.MemoryOffset[i] % prgBankSize == 0) || (memoryType == GbMemoryType.WorkRam && state.MemoryOffset[i] % otherBankSize == 0) || (memoryType == GbMemoryType.CartRam && state.MemoryOffset[i] % otherBankSize == 0) ); if (forceNewBlock || memoryType != state.MemoryType[i] || state.MemoryOffset[i] - state.MemoryOffset[i - 1] != 0x100) { addSection(i); } memoryType = state.MemoryType[i]; accessType = state.MemoryAccessType[i]; } else { if (memoryType != GbMemoryType.None) { addSection(i); } memoryType = GbMemoryType.None; accessType = RegisterAccess.None; } currentSize += 0x100; } //Set work ram mappings to stop at 0xFE00 addSection(-1); regions[regions.Count - 1].Size = 0x1E00; regions.Add(new MemoryRegionInfo() { Name = "", Size = 0x200, Color = Color.FromArgb(222, 222, 222) }); UpdateRegionArray(regions); }
private void UpdateGameboyTab() { GbState gb = _state.Gameboy; List <RegEntry> entries = new List <RegEntry>(); GbPpuState ppu = gb.Ppu; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF40", "LCD Control (LCDC)", null), new RegEntry("$FF40.0", "Background Enabled", ppu.BgEnabled), new RegEntry("$FF40.1", "Sprites Enabled", ppu.BgEnabled), new RegEntry("$FF40.2", "Sprite size", ppu.LargeSprites ? "8x16" : "8x8"), new RegEntry("$FF40.3", "BG Tilemap Select", ppu.BgTilemapSelect ? 0x9C00 : 0x9800, Format.X16), new RegEntry("$FF40.4", "BG Tile Select", ppu.BgTileSelect ? "$8000-$8FFF" : "$8800-$97FF"), new RegEntry("$FF40.5", "Window Enabled", ppu.WindowEnabled), new RegEntry("$FF40.6", "Window Tilemap Select", ppu.WindowTilemapSelect ? 0x9C00 : 0x9800, Format.X16), new RegEntry("$FF40.7", "LCD Enabled", ppu.LcdEnabled), new RegEntry("$FF41", "LCD Status (STAT)", null), new RegEntry("$FF41.0-1", "Mode", (int)ppu.Mode), new RegEntry("$FF41.2", "Coincidence Flag", ppu.LyCoincidenceFlag), new RegEntry("$FF41.3", "Mode 0 H-Blank IRQ", (ppu.Status & 0x08) != 0), new RegEntry("$FF41.4", "Mode 1 V-Blank IRQ", (ppu.Status & 0x10) != 0), new RegEntry("$FF41.5", "Mode 2 OAM IRQ", (ppu.Status & 0x20) != 0), new RegEntry("$FF41.6", "LYC=LY Coincidence IRQ", (ppu.Status & 0x40) != 0), new RegEntry("", "LCD Registers", null), new RegEntry("$FF42", "Scroll Y (SCY)", ppu.ScrollY, Format.X8), new RegEntry("$FF43", "Scroll X (SCX)", ppu.ScrollX, Format.X8), new RegEntry("$FF44", "Y-Coordinate (LY)", ppu.Ly, Format.X8), new RegEntry("$FF45", "LY Compare (LYC)", ppu.LyCompare, Format.X8), new RegEntry("$FF47", "BG Palette (BGP)", ppu.BgPalette, Format.X8), new RegEntry("$FF48", "OBJ Palette 0 (OBP0)", ppu.ObjPalette0, Format.X8), new RegEntry("$FF49", "OBJ Palette 1 (OBP1)", ppu.ObjPalette1, Format.X8), new RegEntry("$FF4A", "Window Y (WY)", ppu.WindowY, Format.X8), new RegEntry("$FF4B", "Window X (WX)", ppu.WindowX, Format.X8), }); GbSquareState sq1 = gb.Apu.Square1; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF10-$FF14", "Square 1", null), new RegEntry("$FF10.0-2", "Sweep Shift", sq1.SweepShift), new RegEntry("$FF10.3", "Sweep Negate", sq1.SweepNegate), new RegEntry("$FF10.4-7", "Sweep Period", sq1.SweepPeriod), new RegEntry("$FF11.0-5", "Length", sq1.Length), new RegEntry("$FF11.6-7", "Duty", sq1.Duty), new RegEntry("$FF12.0-2", "Envelope Period", sq1.EnvPeriod), new RegEntry("$FF12.3", "Envelope Increase Volume", sq1.EnvRaiseVolume), new RegEntry("$FF12.4-7", "Envelope Volume", sq1.EnvVolume), new RegEntry("$FF13+$FF14.0-2", "Frequency", sq1.Frequency), new RegEntry("$FF14.6", "Length Counter Enabled", sq1.LengthEnabled), new RegEntry("$FF14.7", "Channel Enabled", sq1.Enabled), new RegEntry("--", "Timer", sq1.Timer), new RegEntry("--", "Duty Position", sq1.DutyPos), new RegEntry("--", "Sweep Enabled", sq1.SweepEnabled), new RegEntry("--", "Sweep Frequency", sq1.SweepFreq), new RegEntry("--", "Sweep Timer", sq1.SweepTimer), new RegEntry("--", "Envelope Timer", sq1.EnvTimer), new RegEntry("--", "Output", sq1.Output) }); GbSquareState sq2 = gb.Apu.Square2; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF16-$FF19", "Square 2", null), new RegEntry("$FF16.0-5", "Length", sq2.Length), new RegEntry("$FF16.6-7", "Duty", sq2.Duty), new RegEntry("$FF17.0-2", "Envelope Period", sq2.EnvPeriod), new RegEntry("$FF17.3", "Envelope Increase Volume", sq2.EnvRaiseVolume), new RegEntry("$FF17.4-7", "Envelope Volume", sq2.EnvVolume), new RegEntry("$FF18+$FF19.0-2", "Frequency", sq2.Frequency), new RegEntry("$FF19.6", "Length Counter Enabled", sq2.LengthEnabled), new RegEntry("$FF19.7", "Channel Enabled", sq2.Enabled), new RegEntry("--", "Timer", sq2.Timer), new RegEntry("--", "Duty Position", sq2.DutyPos), new RegEntry("--", "Envelope Timer", sq2.EnvTimer), new RegEntry("--", "Output", sq2.Output) }); GbNoiseState noise = gb.Apu.Noise; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF20-$FF23", "Noise", null), new RegEntry("$FF20.0-5", "Length", noise.Length), new RegEntry("$FF21.0-2", "Envelope Period", noise.EnvPeriod), new RegEntry("$FF21.3", "Envelope Increase Volume", noise.EnvRaiseVolume), new RegEntry("$FF21.4-7", "Envelope Volume", noise.EnvVolume), new RegEntry("$FF23.0-2", "Divisor", noise.Divisor), new RegEntry("$FF23.3", "Short Mode", noise.ShortWidthMode), new RegEntry("$FF23.4-7", "Period Shift", noise.PeriodShift), new RegEntry("$FF24.6", "Length Counter Enabled", noise.LengthEnabled), new RegEntry("$FF24.7", "Channel Enabled", noise.Enabled), new RegEntry("--", "Timer", noise.Timer), new RegEntry("--", "Envelope Timer", noise.EnvTimer), new RegEntry("--", "Shift Register", noise.ShiftRegister, Format.X16), new RegEntry("--", "Output", noise.Output) }); GbWaveState wave = gb.Apu.Wave; entries.AddRange(new List <RegEntry>() { new RegEntry("$FF1A-$FF1E", "Wave", null), new RegEntry("$FF1A.7", "Sound Enabled", wave.DacEnabled), new RegEntry("$FF1B", "Length", wave.Length), new RegEntry("$FF1C.5-6", "Volume", wave.Volume), new RegEntry("$FF1D+$FF1E.0-2", "Frequency", wave.Frequency), new RegEntry("$FF1E.6", "Length Counter Enabled", wave.LengthEnabled), new RegEntry("$FF1E.7", "Channel Enabled", wave.Enabled), new RegEntry("--", "Timer", wave.Timer), new RegEntry("--", "Position", wave.SampleBuffer), new RegEntry("--", "Position", wave.Position), new RegEntry("--", "Output", wave.Output), }); ctrlCoprocessor.UpdateState(entries); }