From 9f7ee662f930a0e1b18b8c8606450681bc5179ac Mon Sep 17 00:00:00 2001 From: Sour Date: Sun, 24 May 2020 22:41:54 -0400 Subject: [PATCH] GB: APU - Implemented volume update behavior on register writes Fixes sound in Prehistorik intro --- Core/GbSquareChannel.h | 27 ++++++++++++++++++++++++--- Core/GbTypes.h | 1 + UI/Interop/DebugState.cs | 7 +++---- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Core/GbSquareChannel.h b/Core/GbSquareChannel.h index 68eadae..56e21ba 100644 --- a/Core/GbSquareChannel.h +++ b/Core/GbSquareChannel.h @@ -90,7 +90,7 @@ public: void ClockEnvelope() { - if(_state.EnvTimer > 0) { + if(_state.EnvTimer > 0 && !_state.EnvStopped) { _state.EnvTimer--; if(_state.EnvTimer == 0) { @@ -98,6 +98,8 @@ public: _state.Volume++; } else if(!_state.EnvRaiseVolume && _state.Volume > 0) { _state.Volume--; + } else { + _state.EnvStopped = true; } _state.EnvTimer = _state.EnvPeriod; @@ -170,15 +172,33 @@ public: _state.Duty = (value & 0xC0) >> 6; break; - case 2: + case 2: { + if(_state.EnvPeriod == 0 && !_state.EnvStopped){ + //"If the old envelope period was zero and the envelope is still doing automatic updates, volume is incremented by 1" + _state.Volume++; + } else if(!_state.EnvRaiseVolume) { + //"otherwise if the envelope was in subtract mode, volume is incremented by 2" + _state.Volume += 2; + } + + bool raiseVolume = (value & 0x08) != 0; + if(raiseVolume != _state.EnvRaiseVolume) { + //"If the mode was changed (add to subtract or subtract to add), volume is set to 16 - volume." + _state.Volume = 16 - _state.Volume; + } + + //"Only the low 4 bits of volume are kept after the above operations." + _state.Volume &= 0xF; + _state.EnvPeriod = value & 0x07; - _state.EnvRaiseVolume = (value & 0x08) != 0; + _state.EnvRaiseVolume = raiseVolume; _state.EnvVolume = (value & 0xF0) >> 4; if(!(value & 0xF8)) { _state.Enabled = false; } break; + } case 3: _state.Frequency = (_state.Frequency & 0x700) | value; @@ -204,6 +224,7 @@ public: //Volume envelope timer is reloaded with period. _state.EnvTimer = _state.EnvPeriod; + _state.EnvStopped = false; //Channel volume is reloaded from NRx2. _state.Volume = _state.EnvVolume; diff --git a/Core/GbTypes.h b/Core/GbTypes.h index 5a5a231..0231500 100644 --- a/Core/GbTypes.h +++ b/Core/GbTypes.h @@ -219,6 +219,7 @@ struct GbSquareState bool EnvRaiseVolume; uint8_t EnvPeriod; uint8_t EnvTimer; + bool EnvStopped; uint8_t Duty; uint16_t Frequency; diff --git a/UI/Interop/DebugState.cs b/UI/Interop/DebugState.cs index 73af342..f18bf4f 100644 --- a/UI/Interop/DebugState.cs +++ b/UI/Interop/DebugState.cs @@ -693,6 +693,7 @@ namespace Mesen.GUI public byte H; public byte L; + [MarshalAs(UnmanagedType.I1)] public bool EiPending; [MarshalAs(UnmanagedType.I1)] public bool IME; [MarshalAs(UnmanagedType.I1)] public bool Halted; } @@ -713,6 +714,7 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.I1)] public bool StatIrqFlag; public byte LyCompare; + [MarshalAs(UnmanagedType.I1)] public bool LyCoincidenceFlag; public byte BgPalette; public byte ObjPalette0; public byte ObjPalette1; @@ -735,10 +737,6 @@ namespace Mesen.GUI public UInt32 FrameCount; public byte CgbVramBank; - public UInt16 CgbDmaSource; - public UInt16 CgbDmaDest; - public byte CgbDmaLength; - [MarshalAs(UnmanagedType.I1)] public bool CgbHdmaMode; public byte CgbBgPalPosition; [MarshalAs(UnmanagedType.I1)] public bool CgbBgPalAutoInc; @@ -768,6 +766,7 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.I1)] public bool EnvRaiseVolume; public byte EnvPeriod; public byte EnvTimer; + [MarshalAs(UnmanagedType.I1)] public bool EnvStopped; public byte Duty; public UInt16 Frequency;